diff options
93 files changed, 3228 insertions, 881 deletions
@@ -127,5 +127,8 @@ minishell_history *.core vgcore* qwe -qwe.sh -.clang_complete
\ No newline at end of file +*.sh +noread +.clang_complete +/bash +/mini @@ -15,7 +15,9 @@ LFT_SRCS_DIR = ${LFT_DIR}src/ #==============================================================================# #--------------------------------- FILES --------------------------------------# #==============================================================================# -SRCS_NAME = b_cd +SRCS_NAME = b_alias +SRCS_NAME += b_alias_print +SRCS_NAME += b_cd SRCS_NAME += b_echo SRCS_NAME += b_env SRCS_NAME += b_exit @@ -23,6 +25,11 @@ SRCS_NAME += b_export SRCS_NAME += b_export_next SRCS_NAME += b_export_mute SRCS_NAME += b_pwd +SRCS_NAME += b_sqb +SRCS_NAME += b_sqb_err +SRCS_NAME += b_sqb_file +SRCS_NAME += b_sqb_nbr +SRCS_NAME += b_sqb_str SRCS_NAME += b_type SRCS_NAME += b_unset SRCS_NAME += c_init @@ -31,7 +38,6 @@ SRCS_NAME += c_keys SRCS_NAME += c_utils SRCS_NAME += e_builtins SRCS_NAME += e_externs -SRCS_NAME += e_externs_next SRCS_NAME += e_externs_pipes SRCS_NAME += e_line SRCS_NAME += e_pipes @@ -42,6 +48,7 @@ SRCS_NAME += f_errno SRCS_NAME += f_exec SRCS_NAME += f_fail SRCS_NAME += f_file +SRCS_NAME += f_parse SRCS_NAME += f_redir SRCS_NAME += f_shlvl SRCS_NAME += m_argv @@ -57,14 +64,21 @@ SRCS_NAME += m_redirs SRCS_NAME += s_destroy SRCS_NAME += s_com SRCS_NAME += s_init +SRCS_NAME += s_lalias SRCS_NAME += s_line SRCS_NAME += s_lvars SRCS_NAME += s_lpipes +SRCS_NAME += p_args +SRCS_NAME += p_args_next +SRCS_NAME += p_args_len +SRCS_NAME += p_args_escape SRCS_NAME += p_line -SRCS_NAME += p_lcom -SRCS_NAME += p_lcom_next -SRCS_NAME += p_lcom_vars +SRCS_NAME += p_lblock +SRCS_NAME += p_lblock_next SRCS_NAME += p_split +SRCS_NAME += u_alias +SRCS_NAME += u_parse +SRCS_NAME += u_path SRCS_NAME += u_utils SRCS_NAME += u_vars SRCS_NAME += u_vars_next @@ -6,27 +6,45 @@ ** DONE [#A] /true/path/to/non-existant/bin/fail-plus-bad-fork ** DONE [#A] fix pwd when cd / ** DONE [#A] Multiline pipes (ls |) -** TODO [#A] Go full tok + quotes +** DONE [#A] Go full tok + quotes +** DONE [#A] fix \; \&& \|| +** DONE [#A] Variables quotes qwe="okokoko kkok" asd='bav' +** DONE [#A] Fix PSX \stuff subst with "" '' +** DONE [#A] ls qweqwe; echo $? <---- substitute +** DONE [#A] Don't fuck with '$vars' +** TODO [#A] <>> +** DONE [#A] SEGV on pipes ** DONE [#B] forked write(2) stuff on cd -** TODO [#B] Multiline && || -** TODO [#B] ./qwe.sh <=== handle bad shebang +** DONE [#B] Multiline && || +** DONE [#B] ./qwe.sh <=== handle bad shebang ** DONE [#C] fix that goddamn exit(2) 25 leak -** TODO [#C] lpipes leaks on builtins (same as above man) +** DONE [#C] lpipes leaks on builtins (same as above man) ** DONE [#C] leaks on builtins (same as above man) +** DONE [#C] Variables stack rework ** TODO [#C] Handle memory ** TODO [#C] Go full stack to ken dash in the ass +** DONE [#C] Handle comments better # +** TODO [#C] msh ~> ./qwe.sh <---- without shebang (maybe works fine already) +** TODO [#C] Fix ~ only first pos of arg +** DONE [#C] Fix $? * Stuff to add ** DONE [#A] builtins to pipes ** DONE [#A] Proper ~ subst +** TODO [#A] SIGNAL ** DONE [#B] && || ** TODO [#B] & ** TODO [#B] $_ +** TODO [#B] Parse error before p_line for scripts ** DONE [#B] .minishellrc -** TODO [#B] .minishell_history +** DONE [#B] .minishell_history +** TODO [#B] history builtin ** TODO [#C] Norm -** TODO [#C] [ builtin <=== pretty cool yet simple stuff ( [ $a -eq 1 ] ) -** TODO [#C] alias +** DONE [#C] [ builtin <=== pretty cool yet simple stuff ( [ $a -eq 1 ] ) +** DONE [#C] alias ** DONE [#C] Read scripts ** DONE [#C] PSX rice +** TODO [#C] if else +** TODO [#C] << ** TODO [#C] Termcaps +** TODO [#C] Simple arithmetics $((a + 1)) diff --git a/libft/Makefile b/libft/Makefile index 4e5095b..4489b9a 100644 --- a/libft/Makefile +++ b/libft/Makefile @@ -78,6 +78,7 @@ SRCS_NAME += ft_putnbr_base.c SRCS_NAME += ft_strcat.c SRCS_NAME += ft_strcmp.c SRCS_NAME += ft_isspace.c +SRCS_NAME += ft_iswhitespace.c SRCS_NAME += ft_sqrt.c SRCS_NAME += ft_intlen.c SRCS_NAME += ft_intlen_base.c @@ -111,6 +112,7 @@ SRCS_NAME += ft_printf_process.c SRCS_NAME += ft_printf_cat_output.c SRCS_NAME += ft_printf_flag_to_atoi.c SRCS_NAME += ft_strsubst.c +SRCS_NAME += ft_strsubst_s.c #------------------------------------------------------------------------------# SRCS = $(addprefix ${SRCS_DIR},${SRCS_NAME}) #------------------------------------------------------------------------------# diff --git a/libft/include/libft.h b/libft/include/libft.h index 96615fd..c31482c 100644 --- a/libft/include/libft.h +++ b/libft/include/libft.h @@ -15,7 +15,7 @@ #include <stddef.h> #include <stdarg.h> -#include <inttypes.h> +#include <stdint.h> # define FT_MIN_HEX_BASE "0123456789abcdef" # define FT_MAJ_HEX_BASE "0123456789ABCDEF" @@ -123,6 +123,9 @@ char *ft_nstr(size_t size); char *ft_strsubst(char *str, const char *pattern, const char *subst); +int8_t ft_strsubst_s(char *str, + const char *pattern, + const char *subst); char *ft_strtok_r(char *s, const char *delim, char **last); char *ft_strtok(char *s, const char *delim); char **ft_split(const char *s, char c); @@ -137,6 +140,7 @@ uint8_t ft_uintlen(unsigned long n); uint8_t ft_uintlen_base(unsigned long n, char *base); int ft_memcmp(const void *s1, const void *s2, size_t n); t_bool ft_isspace(int c); +t_bool ft_iswhitespace(int c); t_bool ft_ischarset(const char *charset, int c); t_bool ft_isupper(int c); t_bool ft_islower(int c); diff --git a/libft/src/ft_isspace.c b/libft/src/ft_isspace.c index b9b653f..8454c7c 100644 --- a/libft/src/ft_isspace.c +++ b/libft/src/ft_isspace.c @@ -11,7 +11,6 @@ /* ************************************************************************** */ #include <libft.h> -#include <inttypes.h> t_bool ft_isspace(int c) diff --git a/libft/src/ft_iswhitespace.c b/libft/src/ft_iswhitespace.c new file mode 100644 index 0000000..3bb5868 --- /dev/null +++ b/libft/src/ft_iswhitespace.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_iswhitespace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:06:40 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:06:40 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> + +t_bool + ft_iswhitespace(int c) +{ + if (c == '\t' || + c == '\v' || + c == '\f' || + c == '\r' || + c == ' ') + return (TRUE); + return (FALSE); +} diff --git a/libft/src/ft_nrealloc.c b/libft/src/ft_nrealloc.c index 82975d1..6b42380 100644 --- a/libft/src/ft_nrealloc.c +++ b/libft/src/ft_nrealloc.c @@ -21,7 +21,7 @@ void if (!ptr) { - if (!(ptr = malloc(newsize))) + if ((ptr = malloc(newsize)) == NULL) return (NULL); return (ptr); } @@ -30,7 +30,7 @@ void ft_memdel((void*)&ptr); return (NULL); } - if (!(nptr = malloc(newsize))) + if ((nptr = malloc(newsize)) == NULL) return (ptr); ft_memcpy(nptr, ptr, oldsize); ft_memdel((void*)&ptr); diff --git a/libft/src/ft_strlcpy.c b/libft/src/ft_strlcpy.c index ed4d924..5076a69 100644 --- a/libft/src/ft_strlcpy.c +++ b/libft/src/ft_strlcpy.c @@ -16,9 +16,9 @@ size_t ft_strlcpy(char *dst, const char *src, size_t size) { - size_t src_len; + size_t src_len; - if (!dst || !src) + if (dst == NULL || src == NULL) return (0); src_len = ft_strlen(src); if (src_len + 1 < size) diff --git a/libft/src/ft_strsubst.c b/libft/src/ft_strsubst.c index 57e0ac8..3c5c643 100644 --- a/libft/src/ft_strsubst.c +++ b/libft/src/ft_strsubst.c @@ -20,10 +20,10 @@ char char *nstr; char *ptr; - if (!(ptr = ft_strnstr(str, pattern, ft_strlen(str)))) + if ((ptr = ft_strnstr(str, pattern, ft_strlen(str))) == NULL) return (NULL); nlen = ft_strlen(str) - ft_strlen(pattern) + ft_strlen(subst); - if (!(nstr = (char*)malloc((nlen + 1) * sizeof(char)))) + if ((nstr = (char*)malloc((nlen + 1) * sizeof(char))) == NULL) return (NULL); ft_memcpy(nstr, str, ptr - str); ft_memcpy(nstr + (ptr - str), subst, ft_strlen(subst)); diff --git a/libft/src/ft_strsubst_s.c b/libft/src/ft_strsubst_s.c new file mode 100644 index 0000000..ea61610 --- /dev/null +++ b/libft/src/ft_strsubst_s.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsubst_s.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <stdlib.h> + +int8_t + ft_strsubst_s(char *str, const char *pattern, const char *subst) +{ + char *ptr; + + if ((ptr = ft_strnstr(str, pattern, ft_strlen(str))) == NULL) + return (1); + (void)ft_memmove(str + ((ptr - str) + ft_strlen(subst)), + str + ((ptr - str) + ft_strlen(pattern)), + ft_strlen(str + ((ptr - str) + ft_strlen(pattern))) + 1); + (void)ft_memmove(str + (ptr - str), + subst, + ft_strlen(subst)); + return (0); +} diff --git a/src/b_alias.c b/src/b_alias.c new file mode 100644 index 0000000..5ddc46f --- /dev/null +++ b/src/b_alias.c @@ -0,0 +1,136 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_alias.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> + +#include "b_alias_print.h" +#include "d_define.h" +#include "s_struct.h" +#include "u_alias.h" +#include "u_utils.h" + +static uint8_t + b_print_arg_next(char *ptr, const char arg[], t_bool invalid, t_msh *msh) +{ + char val[ARG_MAX]; + + if (*ptr == C_NUL) + { + if (u_get_alias_value(val, arg, ARG_MAX, msh) != 0) + { + ft_printf("alias %s='%s'", arg, val); + return (0); + } + else + { + ft_dprintf(STDERR_FILENO, "minishell: alias: %s: not found\n", arg); + return (1); + } + } + else if (*ptr == C_EQUALS && invalid == TRUE) + { + ft_strlcpy(val, arg, ptr - arg); + ft_dprintf(STDERR_FILENO, + "minishell: alias: `%s': invalid alias name\n", + val); + return (1); + } + return (0); +} + +static uint8_t + b_print_arg(const char arg[], t_msh *msh) +{ + char *ptr; + t_bool invalid; + + ptr = (char*)arg; + invalid = FALSE; + while (*ptr != C_NUL && *ptr != C_EQUALS) + { + if (ft_iswhitespace(*ptr) == TRUE) + invalid = TRUE; + ptr++; + } + return (b_print_arg_next(ptr, arg, invalid, msh)); +} + +static void + b_register_arg(const char arg[], t_msh *msh) +{ + char *ptr; + char name[255]; + char value[ARG_MAX]; + + ptr = (char*)arg; + while (*ptr != C_NUL && *ptr != C_EQUALS) + { + ptr++; + } + if (*ptr == C_EQUALS) + { + ft_strlcpy(name, arg, (ptr - arg < 255) ? ((ptr - arg) + 1) : (255)); + ptr += 1; + ft_strlcpy(value, ptr, ARG_MAX); + u_set_alias_value(name, value, msh); + } +} + +uint8_t + b_alias(char *args[], t_msh *msh) +{ + const uint64_t argc = u_builtins_get_argc((const char**)args); + int32_t i; + uint8_t ret; + + ret = 0; + if (argc == 0) + { + if (msh->alias == NULL) + return (0); + b_print_alias_list(msh); + } + else if (argc > 0) + { + i = 0; + while (args[i] != NULL) + { + if (b_print_arg(args[i], msh) != 0) + { + ret = 1; + } + i++; + } + } + return (ret); +} + +void + b_alias_mute(char *args[], t_msh *msh) +{ + const uint64_t argc = u_builtins_get_argc((const char**)args); + int32_t i; + + if (argc > 0) + { + i = 0; + while (args[i] != NULL) + { + b_register_arg(args[i], msh); + i++; + } + } +} diff --git a/src/p_lcom_next.h b/src/b_alias.h index 51106e0..83b1878 100644 --- a/src/p_lcom_next.h +++ b/src/b_alias.h @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* p_line_next.h :+: :+: :+: */ +/* b_alias.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -10,14 +10,14 @@ /* */ /* ************************************************************************** */ -#ifndef P_LCOM_NEXT_H -#define P_LCOM_NEXT_H +#ifndef B_ALIAS_H +#define B_ALIAS_H #include <stdint.h> #include "s_struct.h" -char **p_subst_vars(char *words[], t_msh *msh); -char **p_check_args_equals(char *words[], t_msh *msh); +uint8_t b_alias(char *args[], t_msh *msh); +void b_alias_mute(char *args[], t_msh *msh); #endif diff --git a/src/b_alias_print.c b/src/b_alias_print.c new file mode 100644 index 0000000..ebe2708 --- /dev/null +++ b/src/b_alias_print.c @@ -0,0 +1,116 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_alias_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdlib.h> + +#include "d_define.h" +#include "s_struct.h" + +static char + **b_alloc_buff(t_lalias *ptr, size_t i) +{ + char **buff; + + if ((buff = (char**)malloc((i + 1) * sizeof(char*))) == NULL) + return (NULL); + i = 0; + while (ptr != NULL) + { + buff[i + 1] = NULL; + if ((buff[i] = (char*)malloc((6 + ft_strlen(ptr->name) + 2 + + ft_strlen(ptr->val) + 3) * sizeof(char))) == NULL) + { + ft_delwords(buff); + return (NULL); + } + ptr = ptr->next; + i++; + } + return (buff); +} + +static void + b_fill_buff(t_lalias *ptr, char *buff[]) +{ + size_t i; + + i = 0; + while (ptr != NULL) + { + ft_sprintf(buff[i], "alias %s='%s'\n", ptr->name, ptr->val); + ptr = ptr->next; + i++; + } +} + +static void + b_sort_buff(char *buff[]) +{ + size_t i; + int cmp; + char tmp[ARG_MAX]; + + i = 1; + while (buff[i] != NULL) + { + if ((cmp = ft_strncmp(buff[i - 1], buff[i], ARG_MAX)) > 0) + { + ft_strlcpy(tmp, buff[i - 1], ARG_MAX); + ft_memdel((void*)&buff[i - 1]); + if ((buff[i - 1] = ft_strdup(buff[i])) == NULL) + return ; + ft_memdel((void*)&buff[i]); + if ((buff[i] = ft_strdup(tmp)) == NULL) + return ; + i = 0; + } + i++; + } +} + +static void + b_print_buff(char *buff[]) +{ + char **ptr; + + ptr = buff; + while (*ptr != NULL) + { + ft_printf("%s", *ptr); + ptr++; + } +} + +void + b_print_alias_list(t_msh *msh) +{ + t_lalias *ptr; + char **buff; + size_t i; + + ptr = msh->alias; + i = 0; + while (ptr != NULL) + { + ptr = ptr->next; + i++; + } + ptr = msh->alias; + if ((buff = b_alloc_buff(ptr, i)) == NULL) + return ; + ptr = msh->alias; + b_fill_buff(ptr, buff); + b_sort_buff(buff); + b_print_buff(buff); + ft_delwords(buff); +} diff --git a/src/e_externs_next.h b/src/b_alias_print.h index db03bac..a3d2ee3 100644 --- a/src/e_externs_next.h +++ b/src/b_alias_print.h @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* e_externs_next.h :+: :+: :+: */ +/* b_alias_print.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -10,12 +10,11 @@ /* */ /* ************************************************************************** */ -#ifndef E_EXTERNS_NEXT_H -#define E_EXTERNS_NEXT_H +#ifndef B_ALIAS_PRINT_H +#define B_ALIAS_PRINT_H #include "s_struct.h" -char **get_env_path(t_msh *msh); -char *search_in_path(const char com[], char *envpath[], t_msh *msh); +void b_print_alias_list(t_msh *msh); #endif diff --git a/src/b_builtins.h b/src/b_builtins.h index f7e7e99..62b2a41 100644 --- a/src/b_builtins.h +++ b/src/b_builtins.h @@ -13,6 +13,7 @@ #ifndef B_BUILTINS_H #define B_BUILTINS_H +#include "b_alias.h" #include "b_cd.h" #include "b_echo.h" #include "b_env.h" @@ -21,5 +22,6 @@ #include "b_pwd.h" #include "b_type.h" #include "b_unset.h" +#include "b_sqb.h" #endif @@ -16,6 +16,7 @@ #include <linux/limits.h> #include "b_export_next.h" +#include "d_define.h" #include "f_fail.h" #include "s_destroy.h" #include "s_struct.h" @@ -24,39 +25,25 @@ #include "u_vars_next.h" static void - set_path(char **path, - char *args[], - t_msh *msh) -{ - if ((*path = ft_strdup(*args)) == NULL) - { - f_alloc_and_destroy_msh(msh); - } -} - -static void b_set_oldpwd(t_msh *msh) { - char *pwd; - char *tmp; - char fmt[PATH_MAX]; + char pwd[PATH_MAX]; + char tmp[PATH_MAX]; - if ((pwd = u_get_var_value("$PWD", msh)) == NULL) + u_get_var_value(pwd, "$PWD", PATH_MAX, msh); + if (pwd[0] == C_NUL) { - if ((pwd = ft_strdup(msh->cwd)) == NULL) - f_alloc_and_destroy_msh(msh); + ft_strlcpy(pwd, msh->cwd, PATH_MAX); } - if ((tmp = u_get_var_value("$OLDPWD", msh)) == NULL) + u_get_var_value(tmp, "$OLDPWD", PATH_MAX, msh); + if (tmp[0] == C_NUL) { - ft_sprintf(fmt, "%s=%s", "OLDPWD", pwd); - b_export_with_equals(fmt, msh); - ft_memdel((void*)pwd); + ft_sprintf(tmp, "%s=%s", "OLDPWD", pwd); + b_export_with_equals(tmp, msh); } else { u_subst_var_value("$OLDPWD", pwd, msh); - ft_memdel((void*)&pwd); - ft_memdel((void*)&tmp); } } @@ -125,7 +112,7 @@ uint8_t t_msh *msh) { const uint64_t argc = u_builtins_get_argc((const char**)args); - char *path; + char path[PATH_MAX]; if (argc >= 2) { @@ -134,7 +121,8 @@ uint8_t } else if (argc == 0) { - if ((path = u_get_var_value("$HOME", msh)) == NULL) + u_get_var_value(path, "$HOME", PATH_MAX, msh); + if (path[0] == C_NUL) { ft_dprintf(STDERR_FILENO, "minishell: cd: %s\n", FT_FAIL_HOME_NOT_SET); @@ -142,14 +130,12 @@ uint8_t } } else - set_path(&path, args, msh); + ft_strlcpy(path, *args, PATH_MAX); if (chdir(path) != 0) { f_fail_chd("cd", path, msh); - ft_memdel((void*)&path); return (1); } b_upgrade_pwd(path, msh); - ft_memdel((void*)&path); return (0); } diff --git a/src/b_echo.c b/src/b_echo.c index ec66049..b3d4953 100644 --- a/src/b_echo.c +++ b/src/b_echo.c @@ -18,79 +18,16 @@ #include "s_struct.h" #include "u_utils.h" -/* TODO: echo "quoted text", echo 'quoted text', done*/ -/* echo kill\nbackslash\nbut\nnot\nn, echo "quoted\nnew\nlines", done */ -/* full buffer */ - -void - e_put(char *str, - uint8_t op) -{ - size_t i; - - i = -1; - if (op == 0) - while (str[++i]) - { - if (str[i] == '\\') - i++; - ft_putchar(str[i]); - } -} - -char - *e_initb(char *ptr[], - char *str) -{ - size_t len; - uint8_t i; - - len = 0; - i = -1; - while (ptr[++i]) - { - len += ft_strlen(ptr[i]); - } - if (!(str = (char*)malloc(len * sizeof(char)))) - return (NULL); - return (str); -} - -/***********************************************/ -/* void */ -/* e_fill(char *ptr[], char **str) */ -/* { */ -/* char *bs; */ -/* */ -/* ft_sprintf(*str, "%s", *ptr); */ -/* if (*str[0] == '\"' || *str[0] == '\'') */ -/* { */ -/* *str = ft_strtrim(*str, "\"\'"); */ -/* ft_printf("%s", *str); */ -/* } */ -/* else if ((bs = ft_strrchr(*str, '\\'))) */ -/* { */ -/* e_put(*str, 0); */ -/* } */ -/* else */ -/* ft_printf("%s", *str); */ -/* } */ -/***********************************************/ - uint8_t - b_echo(char *args[], - t_msh *msh) + b_echo(char *args[], t_msh *msh) { const uint64_t argc = u_builtins_get_argc((const char **)args); char **ptr; - char *str; int8_t nopt; (void)msh; ptr = args; nopt = 0; - str = NULL; - str = e_initb(ptr, str); if (argc >= 1) { if (ft_strncmp(ptr[0], "-n", 3) == 0) @@ -109,7 +46,6 @@ uint8_t } } } - ft_memdel((void*)&str); if (nopt == 0) ft_printf("\n"); return (0); diff --git a/src/b_export.c b/src/b_export.c index 9987583..aa0c5d0 100644 --- a/src/b_export.c +++ b/src/b_export.c @@ -84,12 +84,11 @@ void } uint8_t - b_export(char *args[], - t_msh *msh) + b_export(char *args[], t_msh *msh) { /* TODO: norme */ char **ptr; - char *varval; + char varval[4096]; char fmt[4096]; t_bool next; uint8_t r; @@ -111,12 +110,11 @@ uint8_t { next = TRUE; ft_sprintf(fmt, "$%s", *ptr); - varval = u_get_cstm_vr(fmt, msh); - if (varval != NULL) + u_get_custom_var(varval, fmt, 4096, msh); + if (varval[0] != C_NUL) { ft_sprintf(fmt, "%s=%s", *ptr, varval); b_add_to_env_from_globals(*ptr, fmt, msh); - ft_memdel((void*)&varval); } } else if (next == FALSE && check_equals(*ptr) == TRUE) diff --git a/src/b_export_mute.c b/src/b_export_mute.c index 4969320..ac72a7e 100644 --- a/src/b_export_mute.c +++ b/src/b_export_mute.c @@ -16,7 +16,7 @@ #include "b_export.h" #include "b_export_next.h" -#include "d_enum.h" +#include "d_define.h" #include "f_fail.h" #include "s_destroy.h" #include "s_line.h" @@ -26,12 +26,11 @@ #include "u_vars.h" uint8_t - b_export_mute(char *args[], - t_msh *msh) + b_export_mute(char *args[], t_msh *msh) { /* TODO: norme */ char **ptr; - char *varval; + char varval[4096]; char fmt[4096]; t_bool next; uint8_t r; @@ -52,12 +51,11 @@ uint8_t { next = TRUE; ft_sprintf(fmt, "$%s", *ptr); - varval = u_get_cstm_vr(fmt, msh); - if (varval != NULL) + u_get_custom_var(varval, fmt, 4096, msh); + if (varval[0] != C_NUL) { ft_sprintf(fmt, "%s=%s", *ptr, varval); b_add_to_env_from_globals(*ptr, fmt, msh); - ft_memdel((void*)&varval); } } else if (next == FALSE && check_equals(*ptr) == TRUE) diff --git a/src/b_export_next.c b/src/b_export_next.c index c46389a..1fc732e 100644 --- a/src/b_export_next.c +++ b/src/b_export_next.c @@ -13,6 +13,7 @@ #include <libft.h> #include <stdlib.h> +#include "d_define.h" #include "b_export_next.h" #include "f_fail.h" #include "s_lvars.h" @@ -21,8 +22,7 @@ #include "u_vars.h" static char - **b_get_var(const char arg[], - t_msh *msh) + **b_get_var(const char arg[], t_msh *msh) { size_t len; char **var; @@ -44,8 +44,7 @@ static char } static int64_t - b_is_it_in_env(const char varname[], - t_msh *msh) + b_is_it_in_env(const char varname[], t_msh *msh) { char **env_dup; size_t i; @@ -66,8 +65,7 @@ static int64_t } static void - b_add_to_env(const char arg[], - t_msh *msh) + b_add_to_env(const char arg[], t_msh *msh) { size_t i; char **nenvp; @@ -92,21 +90,23 @@ static void } void - b_export_with_equals(const char arg[], - t_msh *msh) + b_export_with_equals(const char arg[], t_msh *msh) { - char *varval; + char varval[4096]; char **var; int64_t env_i; + varval[0] = C_NUL; var = b_get_var(arg, msh); if ((env_i = b_is_it_in_env(var[FT_VAR_NAME] + 1, msh)) != -1) { ft_memdel((void*)&msh->envp[env_i]); if ((msh->envp[env_i] = ft_strdup(arg)) == NULL) f_alloc_and_destroy_msh(msh); + return ; } - else if ((varval = u_get_cstm_vr(var[FT_VAR_NAME], msh)) != NULL) + u_get_custom_var(varval, var[FT_VAR_NAME], 4096, msh); + if (varval[0] != C_NUL) { b_add_to_env(arg, msh); lvars_delone(&msh->vars, var[FT_VAR_NAME] + 1); diff --git a/src/b_sqb.c b/src/b_sqb.c new file mode 100644 index 0000000..a5a0fd5 --- /dev/null +++ b/src/b_sqb.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <unistd.h> + +#include "b_sqb_err.h" +#include "b_sqb_file.h" +#include "b_sqb_nbr.h" +#include "b_sqb_str.h" +#include "d_define.h" +#include "s_struct.h" +#include "u_utils.h" + +static uint8_t + b_get_sqb_id(char *argv[], + t_msh *msh) +{ + uint8_t i; + + i = 0; + while (i < FT_ID_SQB_COUNT) + { + if (i < FT_ID_SQB_NT && + ft_strncmp(argv[0], + msh->sqb_ref[i], + ft_strlen(msh->sqb_ref[i]) + 1) == 0) + return (i); + if (i >= FT_ID_SQB_NT && + ft_strncmp(argv[1], + msh->sqb_ref[i], + ft_strlen(msh->sqb_ref[i]) + 1) == 0) + return (i); + i++; + } + return (i); +} + +static uint8_t + b_eval_sqb(char *argv[], + t_msh *msh) +{ + uint8_t id; + uint8_t ret; + + id = b_get_sqb_id(argv, msh); + if (id == FT_ID_SQB_COUNT) + { + ft_dprintf(STDERR_FILENO, "[: %s: unexpected operator\n", argv[0]); + return (2); + } + if (b_sqb_err_check(id, argv) != 0) + return (2); + ret = 0; + if (id < FT_ID_SQB_NT && id != FT_ID_SQB_Z && id != FT_ID_SQB_N) + ret = b_sqb_file_tests(id, argv); + else if (id == FT_ID_SQB_NT || id == FT_ID_SQB_OT) + ret = b_sqb_double_file_tests(id, argv); + else if (id == FT_ID_SQB_N || id == FT_ID_SQB_Z || + id == FT_ID_SQB_EQUA || id == FT_ID_SQB_DIFF) + ret = b_sqb_str(id, argv); + else if (id >= FT_ID_SQB_EQ) + ret = b_sqb_nbr(id, argv); + return (ret); +} + +uint8_t + b_sqb(char *args[], + t_msh *msh) +{ + const uint64_t argc = u_builtins_get_argc((const char**)args); + + if (ft_strncmp(args[argc - 1], "]", 2) != 0) + { + ft_dprintf(STDERR_FILENO, "[: missing ]\n"); + return (2); + } + if (argc == 1) + return (1); + else if (argc == 2) + return (0); + return (b_eval_sqb(args, msh)); +} diff --git a/src/b_sqb.h b/src/b_sqb.h new file mode 100644 index 0000000..c0cfcb8 --- /dev/null +++ b/src/b_sqb.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef B_SQB_H +#define B_SQB_H + +#include <stdint.h> + +#include "s_struct.h" + +uint8_t b_sqb(char *args[], t_msh *msh); + +#endif diff --git a/src/b_sqb_err.c b/src/b_sqb_err.c new file mode 100644 index 0000000..6c68841 --- /dev/null +++ b/src/b_sqb_err.c @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_err.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <unistd.h> + +#include "d_define.h" +#include "u_utils.h" + +static uint8_t + b_single_op(const uint64_t argc, + char *argv[]) +{ + if (argc > 3) + { + ft_dprintf(STDERR_FILENO, "[: %s: unexpected operator\n", argv[1]); + return (1); + } + return (0); +} + +static uint8_t + b_expect_arg(const uint64_t argc, + char *argv[]) +{ + if (argc == 3) + { + ft_dprintf(STDERR_FILENO, "[: %s: argument expected\n", argv[1]); + return (1); + } + return (0); +} + +static uint8_t + b_double_op(const uint64_t argc, + char *argv[]) +{ + if (argc > 4) + { + ft_dprintf(STDERR_FILENO, "[: %s: unexpected operator\n", argv[2]); + return (1); + } + return (0); +} + +static uint8_t + b_bad_nbr(char *argv[]) +{ + char *ptr; + + if (ft_ischarset("+-0123456789", argv[0][0]) == FALSE || + ft_ischarset("+-0123456789", argv[2][0]) == FALSE) + return (1); + ptr = argv[0] + 1; + while (*ptr != '\0') + { + if (ft_isdigit(*ptr) == FALSE) + { + ft_dprintf(STDERR_FILENO, "[: %s: bad number\n", argv[0]); + return (1); + } + ptr++; + } + ptr = argv[2] + 1; + while (*ptr != '\0') + { + if (ft_isdigit(*ptr) == FALSE) + ft_dprintf(STDERR_FILENO, "[: %s: bad number\n", argv[2]); + if (ft_isdigit(*ptr) == FALSE) + return (1); + ptr++; + } + return (0); +} + +uint8_t + b_sqb_err_check(uint8_t id, + char *argv[]) +{ + const uint64_t argc = u_builtins_get_argc((const char**)argv); + + if (id >= FT_ID_SQB_NT) + { + if (b_expect_arg(argc, argv) != 0) + return (1); + } + if (id >= FT_ID_SQB_EQ) + { + if (b_bad_nbr(argv) != 0) + return (1); + } + if (id < FT_ID_SQB_NT) + { + if (b_single_op(argc, argv) != 0) + return (1); + } + else if (id >= FT_ID_SQB_NT) + { + if (b_double_op(argc, argv) != 0) + return (1); + } + return (0); +} diff --git a/src/b_sqb_err.h b/src/b_sqb_err.h new file mode 100644 index 0000000..7c27646 --- /dev/null +++ b/src/b_sqb_err.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_err.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef B_SQB_ERR_H +#define B_SQB_ERR_H + +#include <stdint.h> + +uint8_t b_sqb_err_check(uint8_t id, char *argv[]); + +#endif diff --git a/src/b_sqb_file.c b/src/b_sqb_file.c new file mode 100644 index 0000000..c3a568d --- /dev/null +++ b/src/b_sqb_file.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_file.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <sys/stat.h> +#include <libft.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> + +#include "d_define.h" + +static t_bool + b_file_tests(uint8_t id, + const char path[], + struct stat sb) +{ + if (id == FT_ID_SQB_B && S_ISBLK(sb.st_mode) == 1) + return (TRUE); + else if (id == FT_ID_SQB_C && S_ISCHR(sb.st_mode) == 1) + return (TRUE); + else if (id == FT_ID_SQB_D && S_ISDIR(sb.st_mode) == 1) + return (TRUE); + else if (id == FT_ID_SQB_F && S_ISREG(sb.st_mode) == 1) + return (TRUE); + else if ((id == FT_ID_SQB_H || id == FT_ID_SQB_L_MAJ) + && S_ISLNK(sb.st_mode) == 1) + return (TRUE); + else if (id == FT_ID_SQB_P && S_ISFIFO(sb.st_mode) == 1) + return (TRUE); + else if (id == FT_ID_SQB_R && access(path, R_OK) == 0) + return (TRUE); + else if (id == FT_ID_SQB_S && sb.st_size > 0) + return (TRUE); + else if (id == FT_ID_SQB_W && access(path, W_OK) == 0) + return (TRUE); + else if (id == FT_ID_SQB_X && access(path, X_OK) == 0) + return (TRUE); + else if (id == FT_ID_SQB_S_MAJ && S_ISSOCK(sb.st_mode) == 0) + return (TRUE); + return (FALSE); +} + +uint8_t + b_sqb_file_tests(uint8_t id, + char *argv[]) +{ + struct stat sb; + + if (access(argv[1], 0) == -1) + return (1); + if (id == FT_ID_SQB_E) + return (0); + if (id == FT_ID_SQB_H || id == FT_ID_SQB_L_MAJ) + lstat(argv[1], &sb); + else + stat(argv[1], &sb); + if (b_file_tests(id, argv[1], sb) == TRUE) + return (0); + return (1); +} + +static t_bool + b_sqb_file_comp_tests(uint8_t id, + struct stat sb1, + struct stat sb2) +{ + if (id == FT_ID_SQB_NT && + sb1.st_mtim.tv_sec > sb2.st_mtim.tv_sec) + return (TRUE); + else if (id == FT_ID_SQB_OT && + sb1.st_mtim.tv_sec < sb2.st_mtim.tv_sec) + return (TRUE); + return (FALSE); +} + +uint8_t + b_sqb_double_file_tests(uint8_t id, + char *argv[]) +{ + struct stat sb[2]; + + if (access(argv[0], 0) == -1) + return (1); + if (access(argv[2], 0) == -1) + return (1); + stat(argv[0], &sb[0]); + stat(argv[2], &sb[1]); + if (b_sqb_file_comp_tests(id, sb[0], sb[1]) == TRUE) + return (0); + return (1); +} diff --git a/src/b_sqb_file.h b/src/b_sqb_file.h new file mode 100644 index 0000000..4d9b410 --- /dev/null +++ b/src/b_sqb_file.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_file.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef B_SQB_FILE_H +#define B_SQB_FILE_H + +#include <stdint.h> + +uint8_t b_sqb_file_tests(uint8_t id, char *argv[]); +uint8_t b_sqb_double_file_tests(uint8_t id, char *argv[]); + +#endif diff --git a/src/b_sqb_nbr.c b/src/b_sqb_nbr.c new file mode 100644 index 0000000..6ea2456 --- /dev/null +++ b/src/b_sqb_nbr.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_nbr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> + +#include "d_define.h" + +static t_bool + b_sqb_nbr_tests(uint8_t id, + int32_t n1, + int32_t n2) +{ + if (id == FT_ID_SQB_EQ && n1 == n2) + return (TRUE); + else if (id == FT_ID_SQB_NE && n1 != n2) + return (TRUE); + else if (id == FT_ID_SQB_GT && n1 > n2) + return (TRUE); + else if (id == FT_ID_SQB_GE && n1 >= n2) + return (TRUE); + else if (id == FT_ID_SQB_LT && n1 < n2) + return (TRUE); + else if (id == FT_ID_SQB_LE && n1 <= n2) + return (TRUE); + return (FALSE); +} + +uint8_t + b_sqb_nbr(uint8_t id, + char *argv[]) +{ + if (b_sqb_nbr_tests(id, ft_atoi(argv[0]), ft_atoi(argv[2])) == TRUE) + return (0); + return (1); +} diff --git a/src/b_sqb_nbr.h b/src/b_sqb_nbr.h new file mode 100644 index 0000000..ecdf901 --- /dev/null +++ b/src/b_sqb_nbr.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_nbr.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef B_SQB_NBR_H +#define B_SQB_NBR_H + +#include <stdint.h> + +uint8_t b_sqb_nbr(uint8_t id, char *argv[]); + +#endif diff --git a/src/b_sqb_str.c b/src/b_sqb_str.c new file mode 100644 index 0000000..d3a1978 --- /dev/null +++ b/src/b_sqb_str.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> + +#include "d_define.h" + +static t_bool + b_sqb_str_comp(uint8_t id, + const char s1[], + const char s2[]) +{ + if (id == FT_ID_SQB_EQUA && + ft_strncmp(s1, s2, ft_strlen(s1) + 1) == 0) + return (TRUE); + else if (id == FT_ID_SQB_EQUA && + ft_strncmp(s1, s2, ft_strlen(s1) + 1) != 0) + return (TRUE); + return (FALSE); +} + +uint8_t + b_sqb_str(uint8_t id, + char *argv[]) +{ + if (id == FT_ID_SQB_N) + { + if (argv[1][0] != '\0') + return (0); + else + return (1); + } + else if (id == FT_ID_SQB_Z) + { + if (argv[1][0] == '\0') + return (0); + else + return (1); + } + if (b_sqb_str_comp(id, argv[0], argv[2]) == TRUE) + return (0); + return (1); +} diff --git a/src/b_sqb_str.h b/src/b_sqb_str.h new file mode 100644 index 0000000..9e27973 --- /dev/null +++ b/src/b_sqb_str.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* b_sqb_str.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef B_SQB_STR_H +#define B_SQB_STR_H + +#include <stdint.h> + +uint8_t b_sqb_str(uint8_t id, char *argv[]); + +#endif diff --git a/src/b_type.c b/src/b_type.c index e55a87c..c490aae 100644 --- a/src/b_type.c +++ b/src/b_type.c @@ -15,15 +15,16 @@ #include <dirent.h> #include <fcntl.h> #include <unistd.h> +#include <limits.h> +#include "d_define.h" #include "f_fail.h" #include "s_line.h" #include "s_struct.h" -#include "e_externs_next.h" +#include "u_path.h" #include "u_utils.h" -static int8_t - absolute_path_exists(char com[]) +static int8_t absolute_path_exists(char com[]) { int32_t fd; DIR *dir; @@ -41,78 +42,79 @@ static int8_t return (0); } -static char - *type_get_path(char com[], - t_msh *msh) +static void type_get_path(char fullpath[], char com[], t_msh *msh) { - char **envpath; - char *fullpath; - - envpath = NULL; - fullpath = NULL; if (ft_ischarset("/.", com[0]) == TRUE) { if (absolute_path_exists(com)) { - if (!(fullpath = ft_strdup(com))) - { - f_alloc_and_destroy_msh(msh); - } - return (fullpath); + ft_strlcpy(fullpath, com, PATH_MAX); + return ; } - return (NULL); - } - else if ((envpath = get_env_path(msh)) != NULL) - { - fullpath = search_in_path(com, envpath, msh); - ft_delwords(envpath); + return ; } - return (fullpath); + u_search_in_path(fullpath, com, PATH_MAX, msh); } -static uint8_t - chk_nonbuilt(char **ptr, - t_msh *msh) +static uint8_t b_check_nonbuilt(char *ptr, uint8_t ret, t_msh *msh) { - char *fullpath; - int32_t ret; + char fullpath[PATH_MAX]; - ret = 0; - fullpath = type_get_path(*ptr, msh); - if (fullpath) - ft_printf("%s is %s\n", *ptr, fullpath); + fullpath[0] = C_NUL; + type_get_path(fullpath, ptr, msh); + if (fullpath[0] != C_NUL) + ft_printf("%s is %s\n", ptr, fullpath); else { - ft_printf("minishell: type: %s: not found\n", *ptr); + ft_printf("minishell: type: %s: not found\n", ptr); ret = 1; } - ft_memdel((void*)&fullpath); return (ret); } -uint8_t - b_type(char *args[], - t_msh *msh) +static uint8_t b_check_builtins(char *ptr) +{ + char tmp[M_BUILTINS_REF_LEN]; + char *tok_bu; + + ft_strlcpy(tmp, M_BUILTINS_REF, M_BUILTINS_REF_LEN); + tok_bu = ft_strtok(tmp, ":"); + while (tok_bu != NULL + && ft_strncmp(ptr, tok_bu, ft_strlen(tok_bu) + 1) != 0) + { + tok_bu = ft_strtok(NULL, ":"); + } + if (tok_bu != NULL) + { + ft_printf("%s is a shell builtin\n", ptr); + return (0); + } + return (1); +} + +uint8_t b_type(char *args[], t_msh *msh) { - char **ptr; - char **p_bu; - int32_t ret; + t_lalias *p_alias; + char **ptr; + int32_t ret; ptr = args; - if (!*ptr) + if (*ptr == NULL) return (0); ret = 0; - while (*ptr) + while (*ptr != NULL) { - p_bu = msh->bu_ref; - while (*p_bu && ft_strncmp(*ptr, *p_bu, ft_strlen(*p_bu) + 1)) - p_bu++; - if (*p_bu != NULL) - ft_printf("%s is a shell builtin\n", *ptr); - else + p_alias = msh->alias; + while (p_alias != NULL && + ft_strncmp(*ptr, p_alias->name, + ft_strlen(p_alias->name) + 1) != 0) + p_alias = p_alias->next; + if (p_alias != NULL) { - ret = chk_nonbuilt(ptr, msh); + ft_printf("%s is aliased to `%s'\n", *ptr, p_alias->val); } + else if (b_check_builtins(*ptr) == 1) + ret = b_check_nonbuilt(*ptr, ret, msh); ptr++; } return (ret); diff --git a/src/d_define.h b/src/d_define.h index 9042037..f5dd32e 100644 --- a/src/d_define.h +++ b/src/d_define.h @@ -19,7 +19,8 @@ ** ====== CLASSICS ====== */ -#define FT_BUILTINS "echo|cd|pwd|export|unset|env|exit|type|[" +#define M_BUILTINS_REF "echo:cd:pwd:export:unset:env:exit:type:[:alias" +#define M_BUILTINS_REF_LEN 48 /* ** ====== PSX ====== @@ -51,6 +52,7 @@ #define FT_ZER_VAR "$0" #define FT_RET_VAR "$?" #define FT_PID_VAR "$$" +#define FT_ARGC_VAR "$#" /* ** ====== FAIL MSG ====== @@ -62,10 +64,58 @@ #define FT_FAIL_HOME_NOT_SET "HOME not set" /* +** ====== UTILS ====== +*/ + +#define C_NUL 0x00 +#define C_LF 0x0a +#define C_SUB 0x1a +#define C_ESC 0x1b +#define C_DQUOTE 0x22 +#define C_SHARP 0x23 +#define C_DOLLAR 0x24 +#define C_SQUOTE 0x27 +#define C_AMP 0x26 +#define C_SEMIC 0x3b +#define C_EQUALS 0x3d +#define C_BACKS 0x5c +#define C_PIPE 0x7c + +/* ** ====== FILES ====== */ #define FT_MINISHELLRC ".minishellrc" #define FT_DEFAULT_HISTFILE ".minishell_history" +/* +** ====== SQB OPTIONS ====== +*/ + +#define FT_SQB_B "-b" +#define FT_SQB_C "-c" +#define FT_SQB_D "-d" +#define FT_SQB_E "-e" +#define FT_SQB_F "-f" +#define FT_SQB_H "-h" +#define FT_SQB_N "-n" +#define FT_SQB_P "-p" +#define FT_SQB_R "-r" +#define FT_SQB_S "-s" +#define FT_SQB_W "-w" +#define FT_SQB_X "-x" +#define FT_SQB_Z "-z" +#define FT_SQB_L_MAJ "-L" +#define FT_SQB_S_MAJ "-S" +#define FT_SQB_NT "-nt" +#define FT_SQB_OT "-ot" +#define FT_SQB_EQUA "=" +#define FT_SQB_DIFF "!=" +#define FT_SQB_EQ "-eq" +#define FT_SQB_NE "-ne" +#define FT_SQB_GT "-gt" +#define FT_SQB_GE "-ge" +#define FT_SQB_LT "-lt" +#define FT_SQB_LE "-le" + #endif diff --git a/src/d_enum.h b/src/d_enum.h index c046118..69d34c9 100644 --- a/src/d_enum.h +++ b/src/d_enum.h @@ -32,6 +32,13 @@ enum FT_READ_END }; +typedef enum +{ + Q_NONE, + Q_SINGLE, + Q_DOUBLE +} t_quote_mode; + enum { FT_ID_ECHO, @@ -43,7 +50,38 @@ enum FT_ID_EXIT, FT_ID_TYPE, FT_ID_SQB, + FT_ID_ALIAS, FT_BUILTINS_COUNT }; +enum +{ + FT_ID_SQB_B, + FT_ID_SQB_C, + FT_ID_SQB_D, + FT_ID_SQB_E, + FT_ID_SQB_F, + FT_ID_SQB_H, + FT_ID_SQB_N, + FT_ID_SQB_P, + FT_ID_SQB_R, + FT_ID_SQB_S, + FT_ID_SQB_W, + FT_ID_SQB_X, + FT_ID_SQB_Z, + FT_ID_SQB_L_MAJ, + FT_ID_SQB_S_MAJ, + FT_ID_SQB_NT, + FT_ID_SQB_OT, + FT_ID_SQB_EQUA, + FT_ID_SQB_DIFF, + FT_ID_SQB_EQ, + FT_ID_SQB_NE, + FT_ID_SQB_GT, + FT_ID_SQB_GE, + FT_ID_SQB_LT, + FT_ID_SQB_LE, + FT_ID_SQB_COUNT +}; + #endif diff --git a/src/e_builtins.c b/src/e_builtins.c index 18abc16..90e436e 100644 --- a/src/e_builtins.c +++ b/src/e_builtins.c @@ -16,9 +16,12 @@ #include <stdint.h> #include <unistd.h> +#include "b_builtins.h" #include "b_export_next.h" #include "b_export_mute.h" +#include "m_loop.h" #include "m_redirs.h" +#include "s_com.h" #include "s_destroy.h" #include "s_line.h" #include "s_struct.h" @@ -49,7 +52,8 @@ static void e_export_env_fork(ptr, msh); dup_redirs(ptr, msh); ret = msh->bu_ptr[bu_id](ptr->argv + 1, msh); - u_eof_stdin(); + u_eof_fd(msh->fd); + s_com_destroy(&msh->com); s_line_clear(&msh->curr); s_destroy(msh); exit(ret); @@ -64,7 +68,6 @@ static void int32_t status; int32_t ret; - (void)ptr; while (wait(&status) != pid) ; ret = WEXITSTATUS(status); @@ -75,8 +78,13 @@ static void b_export_mute(ptr->argv + 1, msh); else if (bu_id == FT_ID_UNSET) msh->bu_ptr[bu_id](ptr->argv + 1, msh); - else if (bu_id == FT_ID_EXIT && ret == 0) + else if (bu_id == FT_ID_ALIAS) + b_alias_mute(ptr->argv + 1, msh); + else if (bu_id == FT_ID_EXIT) { + if (msh->fd == STDIN_FILENO) + m_dump_hist(msh); + s_com_destroy(&msh->com); s_line_clear(&msh->curr); s_destroy(msh); exit(ret); diff --git a/src/e_externs.c b/src/e_externs.c index 9e2f8f4..8761986 100644 --- a/src/e_externs.c +++ b/src/e_externs.c @@ -16,28 +16,30 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include <errno.h> #include "b_export_next.h" -#include "e_externs_next.h" +#include "d_define.h" #include "f_fail.h" #include "m_redirs.h" +#include "s_com.h" #include "s_destroy.h" #include "s_line.h" #include "s_struct.h" +#include "u_path.h" #include "u_utils.h" static void e_extern_child(const char *fullpath, - t_com *ptr, - t_msh *msh) + t_com *ptr, + t_msh *msh) { - dup_redirs(ptr, msh); if (execve(fullpath, ptr->argv, msh->envp) == -1) { - f_exec(fullpath); - ft_memdel((void*)&fullpath); - u_eof_stdin(); + f_exec(fullpath, ptr->bin); + u_eof_fd(msh->fd); + s_com_destroy(&msh->com); s_line_clear(&msh->curr); s_destroy(msh); exit(errno); @@ -59,7 +61,7 @@ static void } static void - exec_path(const char fullpath[], + e_exec_path(const char fullpath[], t_com *ptr, t_msh *msh) { @@ -84,33 +86,20 @@ static void } } -void - e_extern(t_com *ptr, - t_msh *msh) +void e_extern(t_com *ptr, t_msh *msh) { - char **envpath; - char *fullpath; + char fullpath[PATH_MAX]; + fullpath[0] = C_NUL; if (ft_ischarset("./", ptr->bin[0]) == TRUE) { - if ((fullpath = ft_strdup(ptr->bin)) == NULL) - return ; - exec_path(fullpath, ptr, msh); - ft_memdel((void*)&fullpath); + ft_strlcpy(fullpath, ptr->bin, PATH_MAX); + e_exec_path(fullpath, ptr, msh); return ; } - else if ((envpath = get_env_path(msh)) != NULL) + else { - fullpath = search_in_path(ptr->bin, envpath, msh); - ft_delwords(envpath); - if (fullpath == NULL) - { - f_fail_command_not_found(ptr->bin, msh); - } - else - { - exec_path(fullpath, ptr, msh); - ft_memdel((void*)&fullpath); - } + u_search_in_path(fullpath, ptr->bin, PATH_MAX, msh); + e_exec_path(fullpath, ptr, msh); } } diff --git a/src/e_externs_next.c b/src/e_externs_next.c deleted file mode 100644 index ed3ee84..0000000 --- a/src/e_externs_next.c +++ /dev/null @@ -1,102 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* e_externs_next.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ -/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ -/* */ -/* ************************************************************************** */ - -#include <libft.h> -#include <dirent.h> -#include <stdlib.h> -#include <stddef.h> - -#include "f_fail.h" -#include "s_destroy.h" -#include "s_line.h" -#include "s_struct.h" -#include "u_utils.h" - -static char - *get_fullpath(const char p_path[], - const char d_name[], - t_msh *msh) -{ - char *fullpath; - const size_t path_len = ft_strlen(p_path); - const size_t name_len = ft_strlen(d_name); - - if (!(fullpath = (char*)malloc((path_len + name_len + 2) * sizeof(char)))) - { - f_alloc_and_destroy_msh(msh); - } - (void)ft_memcpy(fullpath, p_path, path_len); - *(fullpath + (path_len)) = '/'; - (void)ft_memcpy(fullpath + path_len + 1, d_name, name_len); - *(fullpath + (path_len + name_len + 1)) = '\0'; - return (fullpath); -} - -char - *search_in_path(const char com[], - char *envpath[], - t_msh *msh) -{ - struct dirent *ent; - char **p_path; - char *fullpath; - DIR *dir; - - p_path = envpath; - while (*p_path) - { - if ((dir = opendir(*p_path)) != NULL) - { - while ((ent = readdir(dir)) != NULL) - { - /* TODO: check for not bins (dirs, etc) */ - if (ft_strncmp(com, ent->d_name, ft_strlen(com) + 1) == 0) - { - fullpath = get_fullpath(*p_path, ent->d_name, msh); - closedir(dir); - return (fullpath); - } - } - closedir(dir); - } - p_path++; - } - return (NULL); -} - -char - **get_env_path(t_msh *msh) -{ - size_t i; - char **env_dup; - char **envpath; - char *envline; - - env_dup = u_get_env_var_names(msh); - i = 0; - while (env_dup[i] && ft_strncmp("PATH", env_dup[i], 5) != 0) - i++; - if (env_dup[i] == NULL) - return (NULL); - ft_delwords(env_dup); - envline = ft_strchr(msh->envp[i], '='); - envline += 1; - if (*envline != '\0') - { - if ((envpath = ft_split(envline, ':')) == NULL) - { - f_alloc_and_destroy_msh(msh); - } - return (envpath); - } - return (NULL); -} diff --git a/src/e_externs_pipes.c b/src/e_externs_pipes.c index 8556cbb..ca843d0 100644 --- a/src/e_externs_pipes.c +++ b/src/e_externs_pipes.c @@ -16,51 +16,42 @@ #include <stdint.h> #include <unistd.h> #include <string.h> +#include <limits.h> #include <errno.h> #include "d_define.h" -#include "e_externs_next.h" #include "f_fail.h" #include "m_redirs.h" #include "s_destroy.h" #include "s_line.h" #include "s_lpipes.h" #include "s_struct.h" - -static uint8_t - get_builtin_id(const char com[], - t_msh *msh) -{ - uint8_t i; - - i = 0; - while (msh->bu_ref[i] && ft_strncmp(com, msh->bu_ref[i], - ft_strlen(msh->bu_ref[i]) + 1) != 0) - { - i++; - } - return (i); -} +#include "u_path.h" +#include "u_utils.h" static void - e_extern_child(const char *fullpath, - t_com *ptr, - t_msh *msh) + e_pipe_child(char *fullpath[], + uint8_t pipe_id, + t_com *ptr, + t_msh *msh) { uint8_t bu_id; uint8_t ret; dup_redirs(ptr, msh); - if (ft_strncmp(fullpath, "builtin", 8) == 0) + if (ft_strncmp(fullpath[pipe_id], "builtin", 8) == 0) { - bu_id = get_builtin_id(ptr->bin, msh); + bu_id = u_get_builtin_id(ptr->bin); ret = msh->bu_ptr[bu_id](ptr->argv + 1, msh); + u_eof_fd(msh->fd); + s_lpipes_clear(&msh->pipes); s_line_clear(&msh->curr); s_destroy(msh); + ft_delwords(fullpath); exit(ret); } else - execve(fullpath, ptr->argv, msh->envp); + execve(fullpath[pipe_id], ptr->argv, msh->envp); /* TODO: handle execve failed */ } @@ -81,14 +72,14 @@ static size_t } static void - exec_path(const char *fullpath[], - struct s_lpipes *head, - t_msh *msh) + e_pipe_exec_path(char *fullpath[], + struct s_lpipes *head, + t_msh *msh) { + int fd[256][2]; size_t pipes; size_t i; size_t j; - int fd[256][2]; int pid; int status; @@ -116,7 +107,7 @@ static void close(fd[j][FT_READ_END]); j++; } - e_extern_child(fullpath[i], head->com, msh); + e_pipe_child(fullpath, i, head->com, msh); } head = head->next; i++; @@ -138,8 +129,8 @@ void { struct s_lpipes *head; struct s_lpipes *rptr; - char **envpath; char **fullpath; + char tmp[PATH_MAX]; size_t i; size_t pipes; uint8_t bu_id; @@ -147,7 +138,7 @@ void head = ptr; rptr = ptr; pipes = e_get_pipes_count(head); - if (!(fullpath = (char **)malloc((pipes + 2) * sizeof(char *)))) + if ((fullpath = (char **)malloc((pipes + 2) * sizeof(char *))) == NULL) f_alloc_and_destroy_msh(msh); fullpath[pipes + 1] = NULL; i = 0; @@ -158,25 +149,24 @@ void if ((fullpath[i] = ft_strdup(rptr->com->bin)) == NULL) f_alloc_and_destroy_msh(msh); } - else if ((envpath = get_env_path(msh)) != NULL) + else { - if ((bu_id = get_builtin_id(rptr->com->bin, msh)) + if ((bu_id = u_get_builtin_id(rptr->com->bin)) < FT_BUILTINS_COUNT) { if ((fullpath[i] = ft_strdup("builtin")) == NULL) f_alloc_and_destroy_msh(msh); } else - fullpath[i] = search_in_path(rptr->com->bin, envpath, msh); - ft_delwords(envpath); + { + u_search_in_path(tmp, rptr->com->bin, PATH_MAX, msh); + fullpath[i] = ft_strdup(tmp); + } } i++; rptr = rptr->next; } i = 0; - while (fullpath[i] != NULL) - i++; - if (i == (pipes + 1)) - exec_path((const char**)fullpath, head, msh); + e_pipe_exec_path(fullpath, head, msh); ft_delwords(fullpath); } diff --git a/src/e_line.c b/src/e_line.c index 6da7f77..caf3d75 100644 --- a/src/e_line.c +++ b/src/e_line.c @@ -20,60 +20,22 @@ #include "s_lpipes.h" #include "s_com.h" #include "s_struct.h" - -static uint8_t - get_builtin_id(const char bin[], - t_msh *msh) -{ - uint8_t i; - - i = 0; - while (msh->bu_ref[i] != NULL && ft_strncmp(bin, msh->bu_ref[i], - ft_strlen(msh->bu_ref[i]) + 1) != 0) - { - i++; - } - return (i); -} - -static void - e_line_destroy(t_line *ptr) -{ - if (ptr->pipes != NULL) - { - lpipes_clear(&ptr->pipes); - } -} +#include "u_utils.h" void e_line(t_msh *msh) { - t_line *ptr; uint8_t bu_id; - uint8_t previf; - previf = 0; - ptr = msh->curr; - while (ptr != NULL) + if (msh->pipes != NULL) + e_pipes(msh); + else if (msh->com != NULL) { - if ((previf == 0) || (previf == 1 && msh->ret == 0) || - (previf == 2 && msh->ret != 0)) - { - if (ptr->pipes != NULL) - e_pipes(ptr, msh); - else if (ptr->com != NULL) - { - if (ptr->com->bin != NULL && - (bu_id = get_builtin_id(ptr->com->bin, msh)) - < FT_BUILTINS_COUNT) - e_builtin(ptr->com, bu_id, msh); - else if (ptr->com->bin != NULL) - e_extern(ptr->com, msh); - } - } - else - e_line_destroy(ptr); - previf = ptr->nextif; - ptr = ptr->next; + if (msh->com->bin != NULL && + (bu_id = u_get_builtin_id(msh->com->bin)) + < FT_BUILTINS_COUNT) + e_builtin(msh->com, bu_id, msh); + else if (msh->com->bin != NULL) + e_extern(msh->com, msh); } } diff --git a/src/e_pipes.c b/src/e_pipes.c index 30fced2..a1807d1 100644 --- a/src/e_pipes.c +++ b/src/e_pipes.c @@ -35,14 +35,13 @@ /* } */ void - e_pipes(t_line *ptr, - t_msh *msh) + e_pipes(t_msh *msh) { /* uint8_t bu_id; */ /* if ((bu_id = get_builtin_id(ptr->pipes->one->com, msh)) */ /* < FT_BUILTINS_COUNT) */ /* e_builtin(ptr->pipes->one, bu_id, msh); */ - e_externs_pipes(ptr->pipes, msh); - lpipes_clear(&ptr->pipes); + e_externs_pipes(msh->pipes, msh); + s_lpipes_clear(&msh->pipes); } diff --git a/src/e_pipes.h b/src/e_pipes.h index 5bc073a..2f6c550 100644 --- a/src/e_pipes.h +++ b/src/e_pipes.h @@ -15,6 +15,6 @@ #include "s_struct.h" -void e_pipes(t_line *ptr, t_msh *msh); +void e_pipes(t_msh *msh); #endif diff --git a/src/f_exec.c b/src/f_exec.c index 3587700..37cb0f2 100644 --- a/src/f_exec.c +++ b/src/f_exec.c @@ -15,13 +15,23 @@ #include <errno.h> #include <unistd.h> +#include "d_define.h" #include "s_struct.h" -void - f_exec(const char fullpath[]) +void f_exec(const char fullpath[], const char bin[]) { - ft_dprintf(STDERR_FILENO, + if (fullpath[0] != C_NUL) + { + ft_dprintf(STDERR_FILENO, "minishell: %s: %s\n", - fullpath, - strerror(errno)); + fullpath, + strerror(errno)); + } + else + { + ft_dprintf(STDERR_FILENO, + "minishell: %s: %s\n", + bin, + strerror(errno)); + } } diff --git a/src/f_exec.h b/src/f_exec.h index 17f3484..1ea0683 100644 --- a/src/f_exec.h +++ b/src/f_exec.h @@ -15,6 +15,6 @@ #include "s_struct.h" -void f_exec(const char fullpath[]); +void f_exec(const char fullpath[], const char bin[]); #endif diff --git a/src/f_fail.h b/src/f_fail.h index 2e432e2..0046814 100644 --- a/src/f_fail.h +++ b/src/f_fail.h @@ -19,6 +19,7 @@ #include "f_errno.h" #include "f_exec.h" #include "f_file.h" +#include "f_parse.h" #include "f_redir.h" #include "f_shlvl.h" #include "s_struct.h" diff --git a/src/f_parse.c b/src/f_parse.c new file mode 100644 index 0000000..67a7bf1 --- /dev/null +++ b/src/f_parse.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* f_parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <unistd.h> + +void + f_parse_token(char c) +{ + ft_dprintf(STDERR_FILENO, + "minishell: syntax error near unexpected token `%c'", + c); +} diff --git a/src/f_parse.h b/src/f_parse.h new file mode 100644 index 0000000..f6ac496 --- /dev/null +++ b/src/f_parse.h @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* f_parse.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef F_PARSE_H +#define F_PARSE_H + +void f_parse_token(char c); + +#endif diff --git a/src/m_argv.c b/src/m_argv.c index 46e2640..98a8e3e 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -23,13 +23,20 @@ #include "m_mshrc.h" #include "s_struct.h" -uint8_t - m_argv(int argc, - char *const argv[], - t_msh *msh) +static void + m_read_script(char *const argv[], t_msh *msh) { int32_t fd; + if ((fd = open(*(argv + 1), O_RDONLY)) == -1) + f_open_file(*(argv + 1), msh); + msh->ret = m_loop(fd, msh); + close(fd); +} + +uint8_t + m_argv(int argc, char *const argv[], t_msh *msh) +{ if (argc == 1) { m_init_custom_vars(msh); @@ -48,10 +55,7 @@ uint8_t } else { - if ((fd = open(*(argv + 1), O_RDONLY)) < 0) - f_open_file(*(argv + 1), msh); - msh->ret = m_loop(fd, msh); - close(fd); + m_read_script(argv, msh); } return (msh->ret); } diff --git a/src/m_funptr.c b/src/m_funptr.c index 2fdf4d1..bb8d80d 100644 --- a/src/m_funptr.c +++ b/src/m_funptr.c @@ -22,16 +22,14 @@ void init_buptr(t_msh *msh) { - msh->bu_ptr[0] = b_echo; - msh->bu_ptr[1] = b_cd; - msh->bu_ptr[2] = b_pwd; - msh->bu_ptr[3] = b_export; - msh->bu_ptr[4] = b_unset; - msh->bu_ptr[5] = b_env; - msh->bu_ptr[6] = b_exit; - msh->bu_ptr[7] = b_type; - if (!(msh->bu_ref = ft_split(FT_BUILTINS, '|'))) - { - f_alloc_and_destroy_msh(msh); - } + msh->bu_ptr[FT_ID_ECHO] = b_echo; + msh->bu_ptr[FT_ID_CD] = b_cd; + msh->bu_ptr[FT_ID_PWD] = b_pwd; + msh->bu_ptr[FT_ID_EXPORT] = b_export; + msh->bu_ptr[FT_ID_UNSET] = b_unset; + msh->bu_ptr[FT_ID_ENV] = b_env; + msh->bu_ptr[FT_ID_EXIT] = b_exit; + msh->bu_ptr[FT_ID_TYPE] = b_type; + msh->bu_ptr[FT_ID_SQB] = b_sqb; + msh->bu_ptr[FT_ID_ALIAS] = b_alias; } diff --git a/src/m_init.c b/src/m_init.c index c145063..91baf7c 100644 --- a/src/m_init.c +++ b/src/m_init.c @@ -10,17 +10,33 @@ /* */ /* ************************************************************************** */ +#include <libft.h> #include <stdlib.h> +#include <limits.h> +#include "d_define.h" #include "s_struct.h" +#include "u_vars.h" #include "u_vars_next.h" void m_init_custom_vars(t_msh *msh) { + char home[PATH_MAX]; + char fmt[PATH_MAX]; + u_subst_var_value("$PS1", FT_DEFAULT_PS_ONE, msh); u_subst_var_value("$PS2", FT_DEFAULT_PS_TWO, msh); u_subst_var_value("$PS3", FT_DEFAULT_PS_THR, msh); u_subst_var_value("$PS4", FT_DEFAULT_PS_FOU, msh); - u_subst_var_value("$HISTFILE", FT_DEFAULT_HISTFILE, msh); + u_get_var_value(home, "$HISTFILE", PATH_MAX, msh); + if (home[0] == C_NUL) + { + u_get_var_value(home, "$HOME", PATH_MAX, msh); + if (home[0] != C_NUL) + { + ft_sprintf(fmt, "%s/%s", home, FT_DEFAULT_HISTFILE); + u_subst_var_value("$HISTFILE", fmt, msh); + } + } } 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); } diff --git a/src/m_loop.h b/src/m_loop.h index 2fcacf2..1f60744 100644 --- a/src/m_loop.h +++ b/src/m_loop.h @@ -17,7 +17,7 @@ #include "s_struct.h" -void m_parse_and_run_line(char *line, t_msh *msh); +void m_dump_hist(t_msh *msh); uint8_t m_loop(int32_t fd, t_msh *msh); #endif diff --git a/src/m_loop_next.c b/src/m_loop_next.c index 6c0888f..e088cda 100644 --- a/src/m_loop_next.c +++ b/src/m_loop_next.c @@ -14,9 +14,12 @@ #include <stdint.h> #include <unistd.h> +#include "d_define.h" +#include "m_loop_next.h" #include "m_prompt.h" #include "s_struct.h" #include "c_init.h" +#include "u_utils.h" static char *m_counter_line_backslash(int32_t fd, uint8_t psx, char *line, t_msh *msh) @@ -24,7 +27,7 @@ static char char *counter_line; c_gnl(fd, &counter_line, psx, msh); - if (counter_line[0] != 0) + if (counter_line[0] != C_NUL) { line = ft_nrealloc(line, ft_strlen(line) + 1, @@ -43,7 +46,7 @@ static char char *counter_line; c_gnl(fd, &counter_line, psx, msh); - if (counter_line[0] != 0) + if (counter_line[0] != C_NUL) { line = ft_nrealloc(line, ft_strlen(line) + 1, @@ -56,8 +59,31 @@ static char return (line); } +static char + *m_counter_line_quotes(int32_t fd, uint8_t psx, char *line, t_msh *msh) +{ + char *counter_line; + + if (fd == STDIN_FILENO) + m_prompt_psx(psx, msh); + get_next_line(fd, &counter_line); + if (counter_line[0] != C_NUL) + { + line = ft_nrealloc(line, + ft_strlen(line) + 1, + ft_strlen(line) + ft_strlen(counter_line) + 2); + line[ft_strlen(line) + 1] = '\0'; + line[ft_strlen(line)] = '\n'; + ft_memcpy(line + ft_strlen(line), + counter_line, + ft_strlen(counter_line) + 1); + } + ft_memdel((void*)&counter_line); + return (line); +} + char - *m_check_multi_backslash(int32_t fd, char *line, t_msh *msh) + *m_check_multi_backslash(int32_t fd, char line[], t_msh *msh) { if (line[ft_strlen(line) - 1] == '\\') { @@ -68,16 +94,16 @@ char } char - *m_check_multi_pipe(int32_t fd, char *line, t_msh *msh) + *m_check_multi_pipe(int32_t fd, char line[], t_msh *msh) { char *pipe; if ((pipe = ft_strrchr(line, '|')) != NULL) { - pipe++; + pipe += 1; while (*pipe != '\0') { - if (ft_isspace(*pipe) == FALSE) + if (ft_iswhitespace(*pipe) == FALSE) { return (line); } @@ -90,3 +116,114 @@ char return (line); } +char + *m_check_multi_and(int32_t fd, char line[], t_msh *msh) +{ + char *and; + + if ((and = ft_strrchr(line, '&')) != NULL && *(and - 1) == '&') + { + and += 1; + while (*and != '\0') + { + if (ft_iswhitespace(*and) == FALSE) + { + return (line); + } + and++; + } + line = m_counter_line_pipes(fd, 2, line, msh); + line = m_check_multi_backslash(fd, line, msh); + line = m_check_multi_pipe(fd, line, msh); + line = m_check_multi_and(fd, line, msh); + } + return (line); +} + +static t_bool + m_check_dquote(char **ptr, char line[]) +{ + if (((*ptr - line) == 0) || + ((*ptr - line) == 1 && *(*ptr - 1) == C_BACKS) || + ((*ptr - line) > 1 && *(*ptr - 1) == C_BACKS && *(*ptr - 2) != C_BACKS)) + { + return (FALSE); + } + else + { + return (TRUE); + } +} + +static t_bool + m_find_next_quote(char **ptr, char line[], t_quote_mode mode) +{ + char c; + + if (mode == Q_NONE) + return (FALSE); + c = (mode == Q_SINGLE) ? (C_SQUOTE) : (C_DQUOTE); + (*ptr) += 1; + while (**ptr != C_NUL) + { + if (**ptr == c && c == C_DQUOTE) + { + if (m_check_dquote(ptr, line) == FALSE) + { + (*ptr)++; + if (**ptr == C_NUL) + break ; + } + else + return (FALSE); + } + else if (**ptr == c && c == C_SQUOTE) + return (FALSE); + (*ptr)++; + } + return (TRUE); +} + +static t_bool + m_check_missing_quotes(char line[]) +{ + char *ptr; + t_quote_mode mode; + + ptr = line; + mode = Q_NONE; + while (*ptr != C_NUL) + { + if (*ptr == C_SQUOTE || *ptr == C_DQUOTE) + { + if (u_is_not_escaped(line, ptr) == TRUE) + { + mode = (*ptr == C_SQUOTE) ? (Q_SINGLE) : (Q_DOUBLE); + if (m_find_next_quote(&ptr, line, mode) == FALSE) + mode = Q_NONE; + else + return (TRUE); + } + } + ptr++; + } + return (FALSE); +} + +char + *m_check_multi_quotes(int32_t fd, char line[], t_msh *msh) +{ + t_bool reparse; + + reparse = FALSE; + reparse = m_check_missing_quotes(line); + if (reparse == TRUE) + { + line = m_counter_line_quotes(fd, 2, line, msh); + 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); + } + return (line); +} diff --git a/src/m_loop_next.h b/src/m_loop_next.h index 56221e7..b4ca62c 100644 --- a/src/m_loop_next.h +++ b/src/m_loop_next.h @@ -17,8 +17,10 @@ #include "s_struct.h" -char *m_check_multi_backslash(int32_t fd, char *line, t_msh *msh); -char *m_check_multi_pipe(int32_t fd, char *line, t_msh *msh); +char *m_check_multi_backslash(int32_t fd, char line[], t_msh *msh); +char *m_check_multi_pipe(int32_t fd, char line[], t_msh *msh); +char *m_check_multi_and(int32_t fd, char line[], t_msh *msh); +char *m_check_multi_quotes(int32_t fd, char line[], t_msh *msh); #endif diff --git a/src/m_minishell.c b/src/m_minishell.c index a538041..6be605a 100644 --- a/src/m_minishell.c +++ b/src/m_minishell.c @@ -14,6 +14,7 @@ #include <stdint.h> #include <unistd.h> #include <string.h> +#include <unistd.h> #include <errno.h> #include "f_fail.h" @@ -32,7 +33,7 @@ int if ((msh = init_msh(argv, envp)) == NULL) { - ft_dprintf(2, "%s\n", strerror(errno)); + ft_dprintf(STDERR_FILENO, "%s\n", strerror(errno)); return (FT_RET_ALLOC); } ret = m_argv(argc, argv, msh); diff --git a/src/m_mshrc.c b/src/m_mshrc.c index f730113..7f6b8b9 100644 --- a/src/m_mshrc.c +++ b/src/m_mshrc.c @@ -15,6 +15,7 @@ #include <stdlib.h> #include <fcntl.h> #include <unistd.h> +#include <limits.h> #include "d_define.h" #include "s_struct.h" @@ -24,15 +25,13 @@ uint8_t m_source_mshrc(t_msh *msh) { + char file[PATH_MAX]; + char home[PATH_MAX]; int32_t fd; - char *home; - char file[2048]; uint8_t ret; - if ((home = u_get_var_value("$HOME", msh)) == NULL) - return (0); + u_get_var_value(home, "$HOME", PATH_MAX, msh); ft_sprintf(file, "%s/%s", home, FT_MINISHELLRC); - ft_memdel((void*)&home); if ((fd = open(file, O_RDONLY)) < 0) return (0); ret = m_loop(fd, msh); diff --git a/src/m_prompt.c b/src/m_prompt.c index ad3c957..584a98d 100644 --- a/src/m_prompt.c +++ b/src/m_prompt.c @@ -13,6 +13,7 @@ #include <libft.h> #include <stdint.h> #include <unistd.h> +#include <limits.h> #include "d_define.h" #include "m_prompt.h" @@ -20,33 +21,45 @@ #include "u_vars.h" static char - *m_subst_prompt_rice(char var[], - t_msh *msh) + *m_subst_prompt_rice(char var[], t_msh *msh) { + char tmp[PATH_MAX]; size_t i; size_t j; - char *tmp; i = 0; - while (var[i] != '\0') + while (var[i] != C_NUL) { - if (var[i] == '\\') + if (var[i] == C_BACKS) { - if (var[i + 1] == 'w') + if (var[i + 1] == '0' && var[i + 2] == '3' && var[i + 3] == '3') { - tmp = u_get_var_value("$PWD", msh); - if (tmp != NULL) - { - var = ft_strsubst(var, "\\w", tmp); - ft_memdel((void*)&tmp); - } + (void)ft_memmove(var + i, var + (i + 3), (ft_strlen(var + (i + 3)) + 1) * sizeof(char)); + var[i] = C_ESC; + } + else if (var[i + 1] == 'n') + { + (void)ft_memmove(var + i, var + (i + 1), (ft_strlen(var + (i + 1)) + 1) * sizeof(char)); + var[i] = C_LF; + } + else if (var[i + 1] == 'h' || var[i + 1] == 'H') + { + gethostname(tmp, 255); + (void)ft_memmove(var + i + ft_strlen(tmp), var + (i + 2), (ft_strlen(var + (i + 2)) + 1) * sizeof(char)); + (void)ft_memcpy(var + i, tmp, ft_strlen(tmp) * sizeof(char)); + } + else if (var[i + 1] == 'w') + { + u_get_var_value(tmp, "$PWD", PATH_MAX, msh); + if (tmp[0] != C_NUL) + ft_strsubst_s(var, "\\w", tmp); else - var = ft_strsubst(var, "\\w", "?"); + ft_strsubst_s(var, "\\w", "?"); } else if (var[i + 1] == 'W') { - tmp = u_get_var_value("$PWD", msh); - if (tmp != NULL) + u_get_var_value(tmp, "$PWD", PATH_MAX, msh); + if (tmp[0] != C_NUL) { j = ft_strlen(tmp); if (j > 1) @@ -54,18 +67,18 @@ static char while (tmp[j] != '/' && j != 0) j--; j++; - ft_memmove(tmp, tmp + j, (ft_strlen(tmp) - j) + 1); + (void)ft_memmove(tmp, tmp + j, + ((ft_strlen(tmp) - j) + 1) * sizeof(char)); } - var = ft_strsubst(var, "\\W", tmp); - ft_memdel((void*)&tmp); + ft_strsubst_s(var, "\\W", tmp); } else - var = ft_strsubst(var, "\\w", "?"); + ft_strsubst_s(var, "\\w", "?"); } else if (var[i + 1] == 'v') - var = ft_strsubst(var, "\\v", FT_MSH_VERSION); + ft_strsubst_s(var, "\\v", FT_MSH_VERSION); else if (var[i + 1] == 's') - var = ft_strsubst(var, "\\s", FT_PROGNAME); + ft_strsubst_s(var, "\\s", FT_PROGNAME); } i++; } @@ -73,26 +86,24 @@ static char } static void - m_update_psx(uint8_t x, - t_msh *msh) + m_update_psx(uint8_t x, t_msh *msh) { - char *var; + char var[ARG_MAX]; char psx[5]; ft_sprintf(psx, "$PS%hhu", x); - if ((var = u_get_var_value(psx, msh)) == NULL) + u_get_var_value(var, psx, ARG_MAX, msh); + if (var[0] == C_NUL) { msh->ps[x - 1][0] = '\0'; return ; } - var = m_subst_prompt_rice(var, msh); + m_subst_prompt_rice(var, msh); ft_strlcpy(msh->ps[x - 1], var, ft_strlen(var) + 1); - ft_memdel((void*)&var); } void - m_prompt_psx(uint8_t x, - t_msh *msh) + m_prompt_psx(uint8_t x, t_msh *msh) { m_update_psx(x, msh); ft_dprintf(STDERR_FILENO, "%s", msh->ps[x - 1]); diff --git a/src/p_args.c b/src/p_args.c new file mode 100644 index 0000000..54a95a7 --- /dev/null +++ b/src/p_args.c @@ -0,0 +1,158 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <stdlib.h> + +#include "d_define.h" +#include "p_args.h" +#include "p_args_next.h" +#include "p_args_escape.h" +#include "u_parse.h" +#include "u_utils.h" + +static void + p_meet_bs(char *ptr, t_quote_mode mode) +{ + if (mode != Q_SINGLE) + { + if (*(ptr + 1) == C_BACKS) + { + *ptr = C_SUB; + *(ptr + 1) = C_SUB; + } + } +} + +static t_bool + p_meet_whitespace(char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE && u_is_not_escaped(head, ptr) == TRUE) + { + return (TRUE); + } + return (FALSE); +} + +static char + *p_skip_whitespace(char *ptr) +{ + while (*ptr != C_NUL && ft_iswhitespace(*ptr)) + ptr++; + return (ptr); +} + +static uint16_t + p_count_args(const char word[], size_t start[]) +{ + char *ptr; + t_quote_mode mode; + uint16_t count; + + ptr = (char *)word; + mode = Q_NONE; + count = 1; + ptr = p_skip_whitespace(ptr); + start[0] = (ptr - word); + while (*ptr != C_NUL) + { + if (*ptr == C_BACKS) + p_meet_bs(ptr, mode); + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(word, ptr, mode); + else if (*ptr == C_SQUOTE) + mode = u_meet_squote(word, ptr, mode); + if (ft_iswhitespace(*ptr) == TRUE && + p_meet_whitespace((char*)word, ptr, mode) == TRUE) + { + ptr = p_skip_whitespace(ptr); + start[count] = (ptr - word); + if (*ptr != C_NUL) + count += 1; + ptr -= 1; + } + ptr++; + } + return (count); + /* TODO: quotes parse error */ +} + +static char + **p_split_words_no_rdr(const char word[]) +{ + char **words; + size_t start[512]; + uint16_t argc; + uint16_t to_del; + + argc = p_count_args(word, start); + if ((words = (char**)malloc((argc + 1) * sizeof(char*))) == NULL) + return (NULL); + words[argc] = NULL; + if ((to_del = p_dup_words(words, word, argc, start)) != argc) + { + p_del_alloced_words(words, to_del); + return (NULL); + } + p_args_escape_chars_and_quotes(words); + return (words); +} + +char + **p_split_args(char word[], int8_t redir) +{ + char **words; + size_t i; + + words = NULL; + if (redir == 0) + { + if ((words = p_split_words_no_rdr(word)) == NULL) + return (NULL); + return (words); + } + i = ft_strlen(word); + while (ft_ischarset("<>", word[i]) == FALSE) + i--; + i--; + while (redir > 0 && ft_isdigit(word[i]) == TRUE) + i--; + word[i] = C_NUL; + if ((words = p_split_words_no_rdr(word)) == NULL) + return (NULL); + return (words); + /* char **words; */ + /* char *subst; */ + /* size_t i; */ + + /* if (redir == 0) */ + /* { */ + /* if (!(words = ft_split(word, ' '))) */ + /* return (NULL); */ + /* return (words); */ + /* } */ + /* i = 0; */ + /* while (word[i] && ft_ischarset("<>", word[i]) == FALSE) */ + /* i++; */ + /* while (redir > 0 && ft_isdigit(word[i]) == TRUE) */ + /* i--; */ + /* if (!(subst = ft_substr(word, 0, i))) */ + /* return (NULL); */ + /* if (!(words = ft_split(subst, ' '))) */ + /* { */ + /* ft_memdel((void*)&subst); */ + /* return (NULL); */ + /* } */ + /* ft_memdel((void*)&subst); */ + /* return (words); */ +} diff --git a/src/p_args.h b/src/p_args.h new file mode 100644 index 0000000..fa61d92 --- /dev/null +++ b/src/p_args.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef P_ARGS_H +#define P_ARGS_H + +#include <stdint.h> + +char **p_split_args(char word[], int8_t redir); + +#endif diff --git a/src/p_args_escape.c b/src/p_args_escape.c new file mode 100644 index 0000000..abdf3b3 --- /dev/null +++ b/src/p_args_escape.c @@ -0,0 +1,150 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_escape.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stddef.h> + +#include "d_define.h" +#include "u_utils.h" + +static t_quote_mode + p_escape_squote(char *ptr, char **p, char word[], t_quote_mode mode) +{ + if (mode == Q_NONE) + { + if (u_is_not_escaped(word, ptr) == TRUE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + *(p) -= 1; + return (Q_SINGLE); + } + else + { + return (Q_NONE); + } + } + else if (mode == Q_SINGLE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + *(p) -= 1; + return (Q_NONE); + } + return (mode); +} + +static t_quote_mode + p_escape_dquote(char *ptr, char **p, char word[], t_quote_mode mode) +{ + if (mode == Q_NONE) + { + if (u_is_not_escaped(word, ptr) == TRUE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + *(p) -= 1; + return (Q_DOUBLE); + } + else + { + return (Q_NONE); + } + } + else if (mode == Q_DOUBLE && u_is_not_escaped(word, ptr) == TRUE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + *(p) -= 1; + return (Q_NONE); + } + return (mode); +} + +static void + p_escape_bs(char *ptr, char word[], t_quote_mode mode) +{ + if (mode == Q_NONE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + } + else if (mode == Q_DOUBLE) + { + if (*(ptr + 1) == C_BACKS) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + } + else if (*(ptr + 1) == C_DQUOTE) + { + (void)ft_memmove(word + (ptr - word), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + } + } +} + +static void + p_escape_arg(char word[]) +{ + char *ptr; + t_quote_mode mode; + + ptr = word; + mode = Q_NONE; + while (*ptr != C_NUL) + { + if (*ptr == C_SQUOTE) + mode = p_escape_squote(ptr, &ptr, word, mode); + else if (*ptr == C_DQUOTE) + mode = p_escape_dquote(ptr, &ptr, word, mode); + else if (*ptr == C_BACKS) + p_escape_bs(ptr, word, mode); + ptr++; + } +} + +static void + p_replace_bs(char *ptr) +{ + char *head; + + head = ptr; + while (*ptr != C_NUL) + { + if (*ptr == C_SUB && *(ptr + 1) == C_SUB) + { + (void)ft_memmove(head + (ptr - head), ptr + 1, + (ft_strlen(ptr + 1) + 1) * sizeof(char)); + *ptr = C_BACKS; + } + ptr++; + } +} + +void + p_args_escape_chars_and_quotes(char *words[]) +{ + /* TODO: escape \ */ + /* TODO: escape $# special vars */ + /* TODO: comments ################ */ + /* TODO: escape my life */ + char **ptr; + + ptr = words; + while (*ptr != NULL) + { + p_escape_arg(*ptr); + p_replace_bs(*ptr); + ptr++; + } +} diff --git a/src/p_args_escape.h b/src/p_args_escape.h new file mode 100644 index 0000000..746a957 --- /dev/null +++ b/src/p_args_escape.h @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_escape.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef P_ARGS_ESCAPE_H +#define P_ARGS_ESCAPE_H + +void p_args_escape_chars_and_quotes(char *words[]); + +#endif diff --git a/src/p_args_len.c b/src/p_args_len.c new file mode 100644 index 0000000..729e5c5 --- /dev/null +++ b/src/p_args_len.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_len.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stddef.h> + +#include "d_define.h" +#include "u_parse.h" +#include "u_utils.h" + +static t_bool + p_meet_whitespace(const char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE && u_is_not_escaped(head, ptr) == TRUE) + { + return (TRUE); + } + return (FALSE); +} + +size_t + p_arg_len(const char word[], const size_t start) +{ + t_quote_mode mode; + char *ptr; + size_t end; + t_bool terminate; + + mode = Q_NONE; + end = start; + ptr = (char*)word + start; + terminate = FALSE; + while (*ptr != C_NUL && terminate == FALSE) + { + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(word, ptr, mode); + else if (*ptr == C_SQUOTE) + mode = u_meet_squote(word, ptr, mode); + else if (ft_iswhitespace(*ptr) == TRUE) + terminate = p_meet_whitespace(word, ptr, mode); + ptr++; + } + if (terminate == TRUE) + ptr -= 1; + return (ptr - word); +} + diff --git a/src/p_args_len.h b/src/p_args_len.h new file mode 100644 index 0000000..093d8f7 --- /dev/null +++ b/src/p_args_len.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_len.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef P_ARGS_LEN_H +#define P_ARGS_LEN_H + +#include <stddef.h> + +size_t p_arg_len(const char word[], const size_t start); + +#endif diff --git a/src/p_args_next.c b/src/p_args_next.c new file mode 100644 index 0000000..ea8dd81 --- /dev/null +++ b/src/p_args_next.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_next.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <limits.h> + +#include "d_define.h" +#include "p_args.h" +#include "p_args_len.h" + +static char + *p_give_me_an_arg(char tmp[], + const char word[], + const uint16_t i, + const size_t start[]) +{ + tmp[0] = '\0'; + ft_strlcpy(tmp, + word + start[i], + (p_arg_len(word, start[i]) - start[i]) + 1); + return (tmp); +} + +void + p_del_alloced_words(char *words[], uint16_t to_del) +{ + uint16_t i; + + i = 0; + while (i < to_del) + { + ft_memdel((void*)&words[i]); + i++; + } +} + +uint16_t + p_dup_words(char *words[], + const char word[], + const uint16_t argc, + const size_t start[]) +{ + char tmp[ARG_MAX]; + uint16_t i; + + i = 0; + while (i < argc) + { + if ((words[i] = ft_strdup( + p_give_me_an_arg(tmp, word, i, start) + )) == NULL) + return (i); + i++; + } + return (i); +} diff --git a/src/p_args_next.h b/src/p_args_next.h new file mode 100644 index 0000000..365f228 --- /dev/null +++ b/src/p_args_next.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args_next.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef P_ARGS_NEXT_H +#define P_ARGS_NEXT_H + +#include <stdint.h> + +uint16_t p_dup_words(char *words[], + const char word[], + const uint16_t argc, + const size_t start[]); +void p_del_alloced_words(char *words[], uint16_t to_del); + +#endif diff --git a/src/p_lcom.c b/src/p_lblock.c index 13b4d11..377757d 100644 --- a/src/p_lcom.c +++ b/src/p_lblock.c @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* p_lcom.c :+: :+: :+: */ +/* p_lblock.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -25,8 +25,7 @@ #include "s_struct.h" static void - rdr_err_check(char *ptr, - t_com **com) + rdr_err_check(char *ptr, t_com **com) { if ((*com)->redir == -1 && ft_ischarset("><", *(ptr + 1)) == TRUE) { @@ -43,8 +42,7 @@ static void } static int8_t - get_rdrpath(char *ptr, - t_com **com) + get_rdrpath(char *ptr, t_com **com) { char *p_rdrpath; @@ -86,8 +84,7 @@ static void } int8_t - get_redir(const char word[], - t_com **com) + p_get_redir(const char word[], t_com **com) { /* TODO: norme */ char *ptr; @@ -124,25 +121,25 @@ int8_t } int8_t - p_lcom(const char line[], - t_msh *msh) + p_line_block(const char line[], t_msh *msh) { /* TODO: norme */ uint64_t i; - t_line *link; + t_line_block *link; char **words; char *ptr; uint8_t nextif; t_bool next; i = 0; - if ((words = p_split_line(line)) == NULL) + nextif = 0; + if ((words = p_split_line((char*)line)) == NULL) return (-1); while (words[i] != NULL) { - if (words[i][ft_strlen(words[i]) - 1] == ';') + if (words[i][ft_strlen(words[i]) - 1] == '0') nextif = 0; - else if (words[i][ft_strlen(words[i]) - 1] == '&') + else if (words[i][ft_strlen(words[i]) - 1] == '1') nextif = 1; else nextif = 2; @@ -150,15 +147,14 @@ int8_t next = FALSE; if ((ptr = ft_strchr(words[i], '|')) != NULL) { - if ((link = s_line_new(NULL, msh)) == NULL) + if ((link = s_line_new(NULL, 0)) == NULL) return (-1); - if ((split_pipes(words[i], link, msh)) == NULL) + if ((s_split_pipes(words[i], msh)) == NULL) return (-1); next = TRUE; } - if (next == FALSE && (link = s_line_new(words[i], msh)) == NULL) + if (next == FALSE && (link = s_line_new(words[i], nextif)) == NULL) return (-1); - link->nextif = nextif; s_line_add_back(&msh->curr, link); i++; } diff --git a/src/p_lcom.h b/src/p_lblock.h index 2ff2c7e..3979e31 100644 --- a/src/p_lcom.h +++ b/src/p_lblock.h @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* p_lcom.h :+: :+: :+: */ +/* p_lblock.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -17,7 +17,7 @@ #include "s_struct.h" -int8_t get_redir(const char word[], t_com **com); -int8_t p_lcom(const char line[], t_msh *msh); +int8_t p_get_redir(const char word[], t_com **com); +int8_t p_line_block(const char line[], t_msh *msh); #endif diff --git a/src/p_lblock_next.c b/src/p_lblock_next.c new file mode 100644 index 0000000..02ecbb2 --- /dev/null +++ b/src/p_lblock_next.c @@ -0,0 +1,349 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_lblock_next.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdlib.h> +#include <stdint.h> +#include <limits.h> + +#include "d_define.h" +#include "s_destroy.h" +#include "f_fail.h" +#include "s_struct.h" +#include "u_alias.h" +#include "u_parse.h" +#include "u_utils.h" +#include "u_vars.h" +#include "u_vars_next.h" + +/* TODO: norme */ + +static char + *p_double_them_bs(char varval[]) +{ + char *ptr; + + ptr = varval; + while (*ptr != C_NUL) + { + if (*ptr == C_BACKS) + { + ptr = ft_memmove(ptr + 1, ptr, ft_strlen(ptr) + 1); + varval[ptr - varval] = C_BACKS; + } + ptr++; + } + return (varval); +} + +static void + p_subst_this_var(char **p, int64_t i, char word[], t_msh *msh) +{ + char tmp[ARG_MAX]; + char varval[ARG_MAX]; + char *ptr; + size_t varlen; + + ptr = word; + varlen = i + 1; + while (ptr[varlen] != C_NUL && + ft_ischarset("$=\\/@%^*+{}[]<>,.-", ptr[varlen]) == FALSE && + ft_iswhitespace(ptr[varlen]) == FALSE) + varlen += 1; + ft_strlcpy(tmp, ptr + i, varlen + 1 - i); + u_get_var_value(varval, tmp, ARG_MAX, msh); + p_double_them_bs(varval); + ft_strlcpy(ptr + (i + ft_strlen(varval)), + ptr + varlen, + ft_strlen(ptr + varlen) + 1); + (void)ft_memmove(word + i, varval, ft_strlen(varval) * sizeof(char)); + *(p) = word + (i + ft_strlen(varval) - 1); +} + +void + p_subst_vars(char word[], t_msh *msh) +{ + char *ptr; + t_quote_mode mode; + + mode = Q_NONE; + ptr = word; + while (*ptr != C_NUL) + { + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(word, ptr, mode); + else if (*ptr == C_SQUOTE) + mode = u_meet_squote(word, ptr, mode); + if ((mode == Q_NONE || mode == Q_DOUBLE) && *ptr == C_DOLLAR && + u_is_not_escaped(word, ptr) == TRUE) + { + p_subst_this_var(&ptr, (ptr - word), word, msh); + } + ptr++; + } +} + +static char + *p_skip_whitespace(char *ptr) +{ + while (*ptr != C_NUL && ft_iswhitespace(*ptr)) + ptr++; + return (ptr); +} + +static t_bool + p_meet_whitespace(char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE && u_is_not_escaped(head, ptr) == TRUE) + { + return (TRUE); + } + return (FALSE); +} + +size_t + p_subst_alias(char word[], t_bool reset, t_msh *msh) +{ + static size_t used[4096]; + static size_t i = 0; + char value[ARG_MAX]; + char tmp[255]; + size_t locat[2]; + size_t j; + size_t usedcmp; + char *ptr; + t_bool good; + t_quote_mode mode; + + if (reset == TRUE) + { + i = 0; + while (i < 4096) + { + used[i] = 0; + i++; + } + i = 0; + } + mode = Q_NONE; + ptr = word; + ptr = p_skip_whitespace(ptr); + good = TRUE; + locat[0] = (ptr - word); + locat[1] = (ptr - word); + while (*ptr != C_NUL) + { + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(word, ptr, mode); + if (*ptr == C_SQUOTE) + mode = u_meet_squote(word, ptr, mode); + if (mode == Q_NONE && *ptr == C_EQUALS) + good = FALSE; + if (ft_iswhitespace(*ptr) == TRUE && + p_meet_whitespace((char*)word, ptr, mode) == TRUE) + { + locat[1] = (ptr - word); + if (good == TRUE) + break ; + else + { + ptr = p_skip_whitespace(ptr); + locat[0] = (ptr - word); + ptr -= 1; + good = TRUE; + } + } + ptr++; + } + if (*ptr == C_NUL && good == TRUE) + locat[1] = (ptr - word); + if (good == TRUE) + { + ft_strlcpy(tmp, + word + locat[0], + ((locat[1] - locat[0] < 253) ? (locat[1] - locat[0]) : (254)) + 1); + if ((usedcmp = u_get_alias_value(value, tmp, ARG_MAX, msh)) != 0) + { + j = 0; + good = TRUE; + while (j < i) + { + if (used[j] == usedcmp) + good = FALSE; + j++; + } + if (good == TRUE) + { + (void)ft_memmove(word + (locat[0] + ft_strlen(value)), + word + locat[1], + ft_strlen(word + locat[1]) + 1 * sizeof(char)); + (void)ft_memmove(word + locat[0], + value, + ft_strlen(value) * sizeof(char)); + used[i] = usedcmp; + i++; + return (usedcmp); + } + } + } + return (0); +} + +char + **p_subst_home(char *words[], t_msh *msh) +{ + char path[PATH_MAX]; + char **ptr; + + u_get_var_value(path, "$HOME", PATH_MAX, msh); + if (path[0] == C_NUL) + return (words); + ptr = words; + while (*ptr != NULL) + { + if (*ptr[0] == '~') + { + *ptr = ft_strsubst(*ptr, "~", path); + } + ptr++; + } + return (words); +} + +static void + p_register_word(char word[], t_msh *msh) +{ + char name[255]; + char val[255]; + char *ptr; + size_t i; + + name[0] = '$'; + ptr = word; + i = 1; + while (*ptr != '=' && *ptr != '\0') + { + name[i] = *ptr; + i++; + ptr++; + } + name[i] = '\0'; + ptr++; + i = 0; + while (*ptr != '\0') + { + val[i] = *ptr; + i++; + ptr++; + } + val[i] = '\0'; + u_subst_var_value(name, val, msh); +} + +static char + **p_add_to_variables_and_delete(char *words[], + t_bool reg, + int64_t i, + t_msh *msh) +{ + char **rewords; + int64_t j; + int64_t k; + + j = 0; + if (reg == TRUE) + { + while (words[j] && j < i) + { + p_register_word(words[j], msh); + j++; + } + } + j = 0; + while (words[i + j] != NULL) + j++; + if ((rewords = (char**)malloc((j + 1) * sizeof(char*))) == NULL) + { + ft_delwords(words); + f_alloc_and_destroy_msh(msh); + } + k = i; + while (i - k < j) + { + if ((rewords[i - k] = ft_strdup(words[i])) == NULL) + { + ft_delwords(words); + f_alloc_and_destroy_msh(msh); + } + i++; + } + rewords[i - k] = 0; + ft_delwords(words); + i++; + return (rewords); +} + +static void + p_add_to_env_fork(int64_t i, + char *words[], + t_msh *msh) +{ + int64_t j; + + j = 0; + while(j < i) + { + ft_strlcpy(msh->env_fork_tmp[j], words[j], ft_strlen(words[j]) + 1); + j++; + } + msh->env_fork_tmp[j][0] = '\0'; +} + +char + **p_check_args_equals(char *words[], t_msh *msh) +{ + char *ptr; + t_bool reg; + t_bool isvar; + int64_t i; + + i = 0; + reg = FALSE; + isvar = FALSE; + while (words[i]) + { + ptr = words[i]; + while (*ptr != '\0' && *ptr != '=') + ptr++; + if (*ptr == '=') + { + reg = TRUE; + isvar = TRUE; + } + if (*ptr == '\0' || words[i][0] == '=' || + ft_isdigit(words[i][0]) == TRUE) + { + reg = FALSE; + if (i == 0) + isvar = FALSE; + if (isvar == TRUE) + p_add_to_env_fork(i, words, msh); + else + msh->env_fork_tmp[0][0] = '\0'; + break ; + } + i++; + } + if (isvar == TRUE) + return (p_add_to_variables_and_delete(words, reg, i, msh)); + return (words); +} diff --git a/src/p_lblock_next.h b/src/p_lblock_next.h new file mode 100644 index 0000000..4ffdfcf --- /dev/null +++ b/src/p_lblock_next.h @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_lblock_next.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef P_LCOM_NEXT_H +#define P_LCOM_NEXT_H + +#include <libft.h> +#include <stdint.h> + +#include "s_struct.h" + +void p_subst_vars(char word[], t_msh *msh); +size_t p_subst_alias(char word[], t_bool reset, t_msh *msh); +char **p_subst_args(const char word[], int8_t redir); +char **p_subst_home(char *word[], t_msh *msh); +char **p_check_args_equals(char *words[], t_msh *msh); + +#endif diff --git a/src/p_line.c b/src/p_line.c index 8b13424..c8381c8 100644 --- a/src/p_line.c +++ b/src/p_line.c @@ -16,26 +16,10 @@ #include "d_enum.h" #include "f_fail.h" #include "p_line.h" -#include "p_lcom.h" +#include "p_lblock.h" #include "s_destroy.h" #include "s_struct.h" - -static void - p_delete_comments(char line[]) -{ - char *ptr; - - ptr = line; - while (*ptr != '\0') - { - if (*ptr == '#') - { - *ptr = '\0'; - return ; - } - ptr++; - } -} +#include "u_utils.h" static t_bool p_check_whitespaces_only(char line[]) @@ -45,7 +29,7 @@ static t_bool ptr = line; while (*ptr != '\0') { - if (*ptr != ' ' && *ptr != '\t') + if (ft_iswhitespace(*ptr) == FALSE) { return (FALSE); } @@ -55,15 +39,13 @@ static t_bool } void - p_line(char line[], - t_msh *msh) + p_line(char line[], t_msh *msh) { - p_delete_comments(line); if (p_check_whitespaces_only(line) == TRUE) { return ; } - if (p_lcom(line, msh) < 0) + if (p_line_block(line, msh) < 0) { f_alloc_and_destroy_msh(msh); } diff --git a/src/p_split.c b/src/p_split.c index bbe9bf5..dc26c04 100644 --- a/src/p_split.c +++ b/src/p_split.c @@ -12,68 +12,77 @@ #include <libft.h> #include <stdlib.h> +#include <limits.h> -static size_t - p_count_semi_words(const char line[]) -{ - size_t count; - size_t i; +#include "f_fail.h" +#include "d_define.h" +#include "p_split.h" +#include "s_struct.h" +#include "u_parse.h" +#include "u_utils.h" - count = 0; - i = 0; - while (line[i] != '\0') +static void + p_meet_splitter(char *ptr, + const char line[], + t_split_block *sp, + t_quote_mode mode) +{ + if (mode == Q_NONE && *ptr == C_SEMIC && *(ptr + 1) != C_SEMIC && + u_is_not_escaped(line, ptr) == TRUE) + { + sp->pos[sp->count] = (ptr - line); + sp->nextif[sp->count] = 0; + sp->count += 1; + } + else if (mode == Q_NONE && *ptr == C_AMP && *(ptr + 1) == C_AMP && + (*ptr + 2) != C_PIPE && u_is_not_escaped(line, ptr) == TRUE) { - if (line[i] == ';' && line[i + 1] != ';' && line[i + 1] != '\0') - count += 1; - i++; + sp->pos[sp->count] = (ptr - line); + sp->nextif[sp->count] = 1; + sp->count += 1; + } + else if (mode == Q_NONE && *ptr == C_PIPE && *(ptr + 1) == C_PIPE && + *(ptr + 2) != C_PIPE && u_is_not_escaped(line, ptr) == TRUE) + { + sp->pos[sp->count] = (ptr - line); + sp->nextif[sp->count] = 2; + sp->count += 1; } - return (count); } -static size_t - p_count_and_or_words(const char line[], const char c) +static void + p_fill_sp(t_split_block *sp, const char line[]) { - size_t count; - size_t i; + char *ptr; + t_quote_mode mode; - count = 0; - i = 0; - while (line[i] != '\0') + sp->pos[0] = 0; + sp->nextif[0] = 0; + sp->count = 0; + mode = Q_NONE; + ptr = (char*)line; + while (*ptr != C_NUL) { - if (line[i] == c && line[i + 1] == c && - line[i + 2] != c && line[i + 2] != '\0') - count += 1; - i++; + if (*ptr == C_SQUOTE) + mode = u_meet_squote(line, ptr, mode); + else if (*ptr == C_DQUOTE) + mode = u_meet_dquote(line, ptr, mode); + else if (*ptr == C_SEMIC || *ptr == C_AMP || *ptr == C_PIPE) + p_meet_splitter(ptr, line, sp, mode); + ptr++; } - return (count); + sp->pos[sp->count] = ptr - line; + sp->nextif[sp->count] = 0; + sp->count += 1; } -static char - *p_get_first_occur(const char *line_ptr) +static void + *p_del_split(char *words[], size_t todel) { - char *ptr[3]; - size_t len[3]; - - ptr[0] = ft_strnstr(line_ptr, ";", ft_strlen(line_ptr) + 1); - ptr[1] = ft_strnstr(line_ptr, "&&", ft_strlen(line_ptr) + 1); - ptr[2] = ft_strnstr(line_ptr, "||", ft_strlen(line_ptr) + 1); - len[0] = ft_strlen(ptr[0]); - len[1] = ft_strlen(ptr[1]); - len[2] = ft_strlen(ptr[2]); - if (len[0] > len[1] && len[0] > len[2]) - return (ptr[0]); - else if (len[1] > len[0] && len[1] > len[2]) - return (ptr[1]); - else if (len[2] > len[0] && len[2] > len[1]) - return (ptr[2]); - return ((char*)line_ptr); -} + size_t i; -static char - **p_split_destroy(char **words, - size_t i) -{ - while (i > 0) + i = 0; + while (i < todel) { ft_memdel((void*)&words[i]); } @@ -82,62 +91,48 @@ static char } static char - **p_split_to_stuff(const char line[], - const size_t count) + **p_get_words(const char line[], const t_split_block *sp) { char **words; - char *line_ptr; - char *need_ptr; - size_t i; - char c; + int64_t i; + size_t oldpos; + int8_t oldif; - if ((words = (char**)malloc((count + 1) * sizeof(char*))) == NULL) + if ((words = (char**)malloc((sp->count + 1) * sizeof(char*))) == NULL) return (NULL); - line_ptr = (char*)line; - i = 0; - while (i < count) + oldpos = 0; + oldif = -1; + i = -1; + while (++i < sp->count) { - need_ptr = p_get_first_occur(line_ptr); - c = need_ptr[0]; - need_ptr += (c == ';') ? (1) : (0); - need_ptr += (c == '&') ? (2) : (0); - need_ptr += (c == '|') ? (2) : (0); - if (need_ptr - line_ptr == 0) - { - if ((words[i] = (char*)malloc(((ft_strlen(line_ptr) + 2) * - sizeof(char)))) == NULL) - return (p_split_destroy(words, i)); - ft_memcpy(words[i], line_ptr, ft_strlen(line_ptr)); - words[i][ft_strlen(line_ptr)] = ';'; - words[i][ft_strlen(line_ptr) + 1] = '\0'; - } - else - { - if ((words[i] = (char*)malloc(((need_ptr - line_ptr) + 1) * - sizeof(char))) == NULL) - return (p_split_destroy(words, i)); - ft_memcpy(words[i], line_ptr, (need_ptr - line_ptr) - 1); - words[i][(need_ptr - line_ptr) - ((c == ';') ? (1) : (2))] = c; - words[i][(need_ptr - line_ptr) - ((c == ';') ? (0) : (1))] = '\0'; - line_ptr = need_ptr; - } - i++; + if ((words[i] = (char*)malloc(((sp->pos[i] - oldpos) + 2) * + sizeof(char))) == NULL) + return ((char**)p_del_split(words, i)); + ft_strlcpy(words[i], line + oldpos + ((oldif > 0) ? (2) : (oldif) + 1), + sp->pos[i] - oldpos + 1 - ((oldif > 0) ? (2) : (1)) + + ((oldif < 0) ? (1) : (0))); + words[i][ft_strlen(words[i]) + 1] = C_NUL; + words[i][ft_strlen(words[i])] = sp->nextif[i] + 0x30; + oldpos = sp->pos[i]; + oldif = sp->nextif[i]; } words[i] = NULL; return (words); } char - **p_split_line(const char line[]) + **p_split_line(char line[]) { - char **words; - size_t count; + t_split_block sp; + char **words; - count = p_count_semi_words(line); - count += p_count_and_or_words(line, '&'); - count += p_count_and_or_words(line, '|'); - count += 1; - if ((words = p_split_to_stuff(line, count)) == NULL) + words = NULL; + p_fill_sp(&sp, line); + if ((words = p_get_words(line, &sp)) == NULL) + { + ft_memdel((void*)&line); return (NULL); + } + ft_memdel((void*)&line); return (words); } diff --git a/src/p_split.h b/src/p_split.h index 648e01c..00da660 100644 --- a/src/p_split.h +++ b/src/p_split.h @@ -13,6 +13,13 @@ #ifndef P_SPLIT_H #define P_SPLIT_H -char **p_split_line(const char line[]); +typedef struct s_split_block +{ + size_t pos[ARG_MAX / 2]; + int8_t nextif[ARG_MAX / 2]; + uint32_t count; +} t_split_block; + +char **p_split_line(char line[]); #endif diff --git a/src/s_com.c b/src/s_com.c index a9d8f84..ebf7b87 100644 --- a/src/s_com.c +++ b/src/s_com.c @@ -12,23 +12,25 @@ #include <libft.h> #include <stdlib.h> +#include <limits.h> +#include "d_define.h" #include "f_fail.h" -#include "p_lcom.h" -#include "p_lcom_next.h" -#include "p_lcom_vars.h" +#include "p_args.h" +#include "p_lblock.h" +#include "p_lblock_next.h" +>>>>>>> master #include "s_struct.h" static int8_t - fill_com(char *words[], - t_com **com) + s_fill_com(char *words[], t_com **com) { /* TODO: norme is bav (for now)*/ int64_t i; int64_t j; - i = -1; - if (words[0]) + i = 0; + if (words[0] != NULL) { if (((*com)->bin = (char*)malloc((ft_strlen(words[0]) + 1) * sizeof(char))) == NULL) @@ -55,8 +57,7 @@ static int8_t } static void - com_cpy_env_fork(t_com **com, - t_msh *msh) + s_com_cpy_env_fork(t_com **com, t_msh *msh) { size_t i; size_t j; @@ -94,11 +95,12 @@ void } t_com - *s_com_new(char word[], - t_msh *msh) + *s_com_new(char word[], t_msh *msh) { + char nword[ARG_MAX]; t_com *com; char **words; + size_t ret; if ((com = (t_com*)malloc(sizeof(t_com))) == NULL) return (NULL); @@ -108,18 +110,25 @@ t_com com->rdrfd = 0; com->rdrpath = NULL; com->env_fork = NULL; - if (get_redir(word, &com) != 0) - return (NULL); - if ((words = p_subst_args(word, com->redir)) == NULL) + nword[0] = C_NUL; + ft_strlcpy(nword, word, ARG_MAX); + if (p_get_redir(nword, &com) != 0) return (NULL); - if ((words = p_subst_vars(words, msh)) == NULL) + if (msh->alias != NULL) + { + ret = p_subst_alias(nword, TRUE, msh); + while (ret != 0) + ret = p_subst_alias(nword, FALSE, msh); + } + p_subst_vars(nword, msh); + if ((words = p_split_args(nword, com->redir)) == NULL) return (NULL); if ((words = p_subst_home(words, msh)) == NULL) return (NULL); words = p_check_args_equals(words, msh); if (msh->env_fork_tmp[0][0] != '\0') - com_cpy_env_fork(&com, msh); - if (fill_com(words, &com) < 0) + s_com_cpy_env_fork(&com, msh); + if (s_fill_com(words, &com) < 0) { ft_delwords(words); return (NULL); diff --git a/src/s_destroy.c b/src/s_destroy.c index 97a47d8..54f3d4a 100644 --- a/src/s_destroy.c +++ b/src/s_destroy.c @@ -13,6 +13,7 @@ #include <libft.h> #include "s_destroy.h" +#include "s_lalias.h" #include "s_lvars.h" void @@ -20,8 +21,8 @@ void { ft_memdel((void*)&msh->shname); ft_memdel((void*)&msh->cwd); - ft_delwords(msh->bu_ref); ft_delwords(msh->envp); lvars_clear(&msh->vars); + s_lalias_clear(&msh->alias); ft_memdel((void*)&msh); } diff --git a/src/s_init.c b/src/s_init.c index 7f4c6b9..d2cd751 100644 --- a/src/s_init.c +++ b/src/s_init.c @@ -26,6 +26,45 @@ #include "u_vars.h" #include "u_vars_next.h" +static void + s_init_sqb_ref_one(t_msh *msh) +{ + ft_memcpy(msh->sqb_ref[FT_ID_SQB_B], FT_SQB_B, ft_strlen(FT_SQB_B) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_C], FT_SQB_C, ft_strlen(FT_SQB_C) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_D], FT_SQB_D, ft_strlen(FT_SQB_D) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_E], FT_SQB_E, ft_strlen(FT_SQB_E) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_F], FT_SQB_F, ft_strlen(FT_SQB_F) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_H], FT_SQB_H, ft_strlen(FT_SQB_H) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_N], FT_SQB_N, ft_strlen(FT_SQB_N) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_P], FT_SQB_P, ft_strlen(FT_SQB_P) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_R], FT_SQB_R, ft_strlen(FT_SQB_R) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_S], FT_SQB_S, ft_strlen(FT_SQB_S) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_W], FT_SQB_W, ft_strlen(FT_SQB_W) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_X], FT_SQB_X, ft_strlen(FT_SQB_X) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_Z], FT_SQB_Z, ft_strlen(FT_SQB_Z) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_L_MAJ], + FT_SQB_L_MAJ, ft_strlen(FT_SQB_L_MAJ) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_S_MAJ], + FT_SQB_S_MAJ, ft_strlen(FT_SQB_S_MAJ) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_NT], FT_SQB_NT, ft_strlen(FT_SQB_NT) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_OT], FT_SQB_OT, ft_strlen(FT_SQB_OT) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_EQUA], + FT_SQB_EQUA, ft_strlen(FT_SQB_EQUA) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_DIFF], + FT_SQB_DIFF, ft_strlen(FT_SQB_DIFF) + 1); +} + +static void + s_init_sqb_ref_two(t_msh *msh) +{ + ft_memcpy(msh->sqb_ref[FT_ID_SQB_EQ], FT_SQB_EQ, ft_strlen(FT_SQB_EQ) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_NE], FT_SQB_NE, ft_strlen(FT_SQB_NE) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_GT], FT_SQB_GT, ft_strlen(FT_SQB_GT) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_GE], FT_SQB_GE, ft_strlen(FT_SQB_GE) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_LT], FT_SQB_LT, ft_strlen(FT_SQB_LT) + 1); + ft_memcpy(msh->sqb_ref[FT_ID_SQB_LE], FT_SQB_LE, ft_strlen(FT_SQB_LE) + 1); +} + static char **dupenv_del(char **nenvp, uint64_t i) @@ -68,80 +107,81 @@ static char static void inc_shlvl(t_msh *msh) { - int32_t shlvl; - char *str_one; - char *str_two; - char *tmp; char fmt[8]; + char tmp[255]; + char *str; + int32_t shlvl; - if ((tmp = u_get_var_value("$SHLVL", msh)) == NULL) + u_get_var_value(tmp, "$SHLVL", 255, msh); + if (tmp[0] == C_NUL) { ft_memcpy(fmt, "SHLVL=1", 8); b_export_with_equals(fmt, msh); } else { - ft_memdel((void*)&tmp); - str_two = u_get_var_value("$SHLVL", msh); - shlvl = ft_atoi(str_two); + shlvl = ft_atoi(tmp); if (shlvl >= 999) f_shlvl_too_high(shlvl); shlvl = (shlvl >= 999) ? 0 : shlvl; shlvl = (shlvl < 0) ? 0 : shlvl + 1; - str_one = ft_itoa(shlvl); - u_subst_var_value("$SHLVL", str_one, msh); - ft_memdel((void*)&str_one); - ft_memdel((void*)&str_two); + str = ft_itoa(shlvl); + u_subst_var_value("$SHLVL", str, msh); + ft_memdel((void*)&str); } } -static char - *set_cwd(t_msh *msh) +static void + set_cwd(char cwd[], t_msh *msh) { - char *cwd; char fmt[PATH_MAX]; DIR *dir; - if ((cwd = u_get_var_value("$PWD", msh)) == NULL) + u_get_var_value(cwd, "$PWD", PATH_MAX, msh); + if (cwd[0] == C_NUL) { - cwd = getcwd(NULL, 0); + getcwd(cwd, PATH_MAX); ft_sprintf(fmt, "%s=%s", "PWD", cwd); b_export_with_equals(fmt, msh); - return (cwd); + return ; } if ((dir = opendir(cwd)) != NULL) closedir(dir); else if (errno == ENOENT) { - ft_memdel((void*)&cwd); - cwd = getcwd(NULL, 0); + getcwd(cwd, PATH_MAX); ft_sprintf(fmt, "%s=%s", "PWD", cwd); b_export_with_equals(fmt, msh); - return (cwd); + return ; } - return (cwd); } t_msh - *init_msh(char *const argv[], - char *const envp[]) + *init_msh(char *const argv[], char *const envp[]) { + char cwd[PATH_MAX]; t_msh *msh; - if (!(msh = (t_msh*)malloc(sizeof(t_msh)))) + if ((msh = (t_msh*)malloc(sizeof(t_msh))) == NULL) return (NULL); - if (!(msh->shname = ft_strdup(argv[0]))) + if ((msh->shname = ft_strdup(argv[0])) == NULL) return (NULL); - /* TODO: shname: care about "./", try with symlinks */ msh->envp = NULL; - if (!(msh->envp = dupenv(envp))) + if ((msh->envp = dupenv(envp)) == NULL) return (NULL); msh->ret = 0; init_buptr(msh); msh->curr = NULL; + msh->com = NULL; + msh->pipes = NULL; msh->vars = NULL; - msh->cwd = set_cwd(msh); + msh->alias = NULL; + set_cwd(cwd, msh); + if ((msh->cwd = ft_strdup(cwd)) == NULL) + return (NULL); msh->env_fork_tmp[0][0] = '\0'; inc_shlvl(msh); + s_init_sqb_ref_one(msh); + s_init_sqb_ref_two(msh); return (msh); } diff --git a/src/s_lalias.c b/src/s_lalias.c new file mode 100644 index 0000000..a31909b --- /dev/null +++ b/src/s_lalias.c @@ -0,0 +1,95 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* s_lalias.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include "s_struct.h" + +void + s_lalias_rebind(t_lalias **lalias, const char name[], const char newval[]) +{ + t_lalias *tmp; + + tmp = *lalias; + while (tmp != NULL && ft_strncmp(tmp->name, name, ft_strlen(name) + 1) != 0) + { + tmp = tmp->next; + } + if (tmp == NULL) + { + return ; + } + ft_memdel((void*)&tmp->val); + if ((tmp->val = ft_strdup(newval)) == NULL) + { + ft_dprintf(STDERR_FILENO, "%s\n", strerror(errno)); + } +} + +void + s_lalias_add_front(t_lalias **lalias, t_lalias *new) +{ + if (lalias == NULL || new == NULL) + { + return ; + } + new->next = *lalias; + *lalias = new; +} + +void + s_lalias_clear(t_lalias **lalias) +{ + t_lalias *tmp; + t_lalias *renext; + + if (lalias == NULL) + return ; + tmp = *lalias; + while (tmp != NULL) + { + renext = tmp->next; + ft_memdel((void*)&tmp->name); + ft_memdel((void*)&tmp->val); + ft_memdel((void*)&tmp); + tmp = renext; + } + *lalias = NULL; +} + +t_lalias + *s_lalias_new(const char name[], const char val[]) +{ + t_lalias *link; + static size_t id = 1; + + if ((link = (t_lalias*)malloc(sizeof(t_lalias))) == NULL) + { + return (NULL); + } + if ((link->name = ft_strdup(name)) == NULL) + { + return (NULL); + } + if ((link->val = ft_strdup(val)) == NULL) + { + return (NULL); + } + link->id = id; + link->next = NULL; + id += 1; + return (link); +} diff --git a/src/s_lalias.h b/src/s_lalias.h new file mode 100644 index 0000000..5218a88 --- /dev/null +++ b/src/s_lalias.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* s_lalias.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef S_LALIAS_H +#define S_LALIAS_H + +#include "s_struct.h" + +void s_lalias_rebind(t_lalias **lalias, + const char name[], + const char newval[]); +void s_lalias_add_front(t_lalias **lalias, t_lalias *new); +void s_lalias_clear(t_lalias **lalias); +t_lalias *s_lalias_new(const char name[], const char val[]); + +#endif diff --git a/src/s_line.c b/src/s_line.c index b47b453..c6e2e0b 100644 --- a/src/s_line.c +++ b/src/s_line.c @@ -14,26 +14,30 @@ #include <stdlib.h> #include <stdint.h> +#include "d_define.h" #include "p_line.h" #include "s_com.h" #include "s_struct.h" -t_line - *s_line_last(t_line *line) +t_line_block + *s_line_last(t_line_block *line) { while (line->next != NULL) + { line = line->next; + } return (line); } void - s_line_add_back(t_line **aline, - t_line *new) + s_line_add_back(t_line_block **aline, t_line_block *new) { - t_line *tmp; + t_line_block *tmp; - if (!*aline) + if (*aline == NULL) + { *aline = new; + } else { tmp = s_line_last(*aline); @@ -42,45 +46,44 @@ void } void - s_line_clear(t_line **line) + s_line_clear(t_line_block **line) { - t_line *tmp; - t_line *renext; + t_line_block *tmp; + t_line_block *renext; - if (!line) + if (line == NULL) + { return ; + } tmp = *line; while (tmp != NULL) { renext = tmp->next; - if (tmp->com != NULL) - { - s_com_destroy(&tmp->com); - } + ft_memdel((void*)&tmp->lblock); ft_memdel((void*)&tmp); tmp = renext; } *line = NULL; } -t_line - *s_line_new(const char word[], - t_msh *msh) +t_line_block + *s_line_new(const char word[], uint8_t nextif) { - t_line *link; + t_line_block *link; - if ((link = (t_line*)malloc(sizeof(t_line))) == NULL) + if ((link = (t_line_block*)malloc(sizeof(t_line_block))) == NULL) return (NULL); - link->nextif = 0; - link->com = NULL; - link->pipes = NULL; + link->lblock = NULL; + link->nextif = nextif; link->next = NULL; if (word == NULL) { link->next = NULL; return (link); } - link->com = s_com_new(word, msh); - /* TODO: check link->com = NULL */ + else if ((link->lblock = ft_strdup(word)) == NULL) + { + return (NULL); + } return (link); } diff --git a/src/s_line.h b/src/s_line.h index cd2211b..b46643f 100644 --- a/src/s_line.h +++ b/src/s_line.h @@ -13,11 +13,13 @@ #ifndef S_LCOM_H #define S_LCOM_H +#include <stdint.h> + #include "s_struct.h" -void s_line_add_back(t_line **aline, t_line *new); -void s_line_clear(t_line **line); -t_line *s_line_new(const char word[], t_msh *msh); -t_line *s_line_last(t_line *line); +void s_line_add_back(t_line_block **aline, t_line_block *new); +void s_line_clear(t_line_block **line); +t_line_block *s_line_new(const char word[], uint8_t nextif); +t_line_block *s_line_last(t_line_block *line); #endif diff --git a/src/s_lpipes.c b/src/s_lpipes.c index 9d10849..04320b8 100644 --- a/src/s_lpipes.c +++ b/src/s_lpipes.c @@ -20,7 +20,7 @@ #include "s_struct.h" struct s_lpipes - *lpipes_last(struct s_lpipes *lpipes) + *s_lpipes_last(struct s_lpipes *lpipes) { while (lpipes->next != NULL) lpipes = lpipes->next; @@ -28,7 +28,7 @@ struct s_lpipes } void - lpipes_add_back(struct s_lpipes **alpipes, + s_lpipes_add_back(struct s_lpipes **alpipes, struct s_lpipes *new) { struct s_lpipes *tmp; @@ -37,13 +37,13 @@ void *alpipes = new; else { - tmp = lpipes_last(*alpipes); + tmp = s_lpipes_last(*alpipes); tmp->next = new; } } void - lpipes_clear(struct s_lpipes **lpipes) + s_lpipes_clear(struct s_lpipes **lpipes) { struct s_lpipes *tmp; struct s_lpipes *renext; @@ -62,12 +62,11 @@ void } struct s_lpipes - *lpipes_new(const char pipedword[], - t_msh *msh) + *s_lpipes_new(const char pipedword[], t_msh *msh) { struct s_lpipes *link; - if (!(link = (struct s_lpipes*)malloc(sizeof(struct s_lpipes)))) + if ((link = (struct s_lpipes*)malloc(sizeof(struct s_lpipes))) == NULL) return (NULL); link->com = NULL; if ((link->com = s_com_new(pipedword, msh)) == NULL) @@ -79,9 +78,7 @@ struct s_lpipes } struct s_lpipes - *split_pipes(const char word[], - t_line *line, - t_msh *msh) + *s_split_pipes(const char word[], t_msh *msh) { struct s_lpipes *lpipes; char **words; @@ -92,11 +89,11 @@ struct s_lpipes i = 0; while (words[i]) { - if (!(lpipes = lpipes_new(words[i], msh))) + if (!(lpipes = s_lpipes_new(words[i], msh))) { return (NULL); } - lpipes_add_back(&line->pipes, lpipes); + s_lpipes_add_back(&msh->pipes, lpipes); i++; } ft_delwords(words); diff --git a/src/s_lpipes.h b/src/s_lpipes.h index 7b90d2c..e2b3f40 100644 --- a/src/s_lpipes.h +++ b/src/s_lpipes.h @@ -15,11 +15,11 @@ #include "s_struct.h" -struct s_lpipes *lpipes_last(struct s_lpipes *lpipes); -void lpipes_add_back(struct s_lpipes **alpipes, +struct s_lpipes *s_lpipes_last(struct s_lpipes *lpipes); +void s_lpipes_add_back(struct s_lpipes **alpipes, struct s_lpipes *new); -void lpipes_clear(struct s_lpipes **lpipes); -struct s_lpipes *lpipes_new(const char pipedword[], t_msh *msh); -struct s_lpipes *split_pipes(const char word[], t_line *line, t_msh *msh); +void s_lpipes_clear(struct s_lpipes **lpipes); +struct s_lpipes *s_lpipes_new(const char pipedword[], t_msh *msh); +struct s_lpipes *s_split_pipes(const char word[], t_msh *msh); #endif diff --git a/src/s_lvars.c b/src/s_lvars.c index 9369f84..e4b054e 100644 --- a/src/s_lvars.c +++ b/src/s_lvars.c @@ -11,22 +11,20 @@ /* ************************************************************************** */ #include <libft.h> -#include <string.h> #include <stdlib.h> +#include <string.h> #include <errno.h> #include <unistd.h> #include "s_struct.h" void - lvars_rebind(t_lvars **lvars, - const char name[], - const char newval[]) + lvars_rebind(t_lvars **lvars, const char name[], const char newval[]) { t_lvars *tmp; tmp = *lvars; - while (tmp && ft_strncmp(tmp->name, name, ft_strlen(name) + 1)) + while (tmp != NULL && ft_strncmp(tmp->name, name, ft_strlen(name) + 1) != 0) { tmp = tmp->next; } @@ -35,16 +33,14 @@ void return ; } ft_memdel((void*)&tmp->val); - if (!(tmp->val = ft_strdup(newval))) + if ((tmp->val = ft_strdup(newval)) == NULL) { ft_dprintf(STDERR_FILENO, "%s\n", strerror(errno)); - exit(FT_RET_ALLOC); } } void - lvars_delone(t_lvars **lvars, - const char name[]) + lvars_delone(t_lvars **lvars, const char name[]) { t_lvars *tmp; t_lvars *prev; @@ -72,10 +68,9 @@ void } void - lvars_add_front(t_lvars **alvars, - t_lvars *new) + lvars_add_front(t_lvars **alvars, t_lvars *new) { - if (!alvars || !new) + if (alvars == NULL || new == NULL) { return ; } @@ -89,10 +84,10 @@ void t_lvars *tmp; t_lvars *renext; - if (!lvars) + if (lvars == NULL) return ; tmp = *lvars; - while (tmp) + while (tmp != NULL) { renext = tmp->next; ft_memdel((void*)&tmp->name); @@ -104,20 +99,19 @@ void } t_lvars - *lvars_new(const char name[], - const char val[]) + *lvars_new(const char name[], const char val[]) { t_lvars *link; - if (!(link = (t_lvars*)malloc(sizeof(t_lvars)))) + if ((link = (t_lvars*)malloc(sizeof(t_lvars))) == NULL) { return (NULL); } - if (!(link->name = ft_strdup(name))) + if ((link->name = ft_strdup(name)) == NULL) { return (NULL); } - if (!(link->val = ft_strdup(val))) + if ((link->val = ft_strdup(val)) == NULL) { return (NULL); } diff --git a/src/s_struct.h b/src/s_struct.h index 15505d5..871b0f4 100644 --- a/src/s_struct.h +++ b/src/s_struct.h @@ -14,9 +14,25 @@ #define S_STRUCT_H #include <stdint.h> +#include <limits.h> #include "d_define.h" +typedef struct s_lvars +{ + char *name; + char *val; + struct s_lvars *next; +} t_lvars; + +typedef struct s_lalias +{ + char *name; + char *val; + size_t id; + struct s_lalias *next; +} t_lalias; + /* ** redir(int8_t) index ** ------------------- @@ -26,27 +42,20 @@ ** 0: means no redirection */ -typedef struct s_lvars -{ - char *name; - char *val; - struct s_lvars *next; -} t_lvars; - -typedef struct s_com +typedef struct s_com { - char *bin; - char **argv; - int8_t redir; - int32_t rdrfd; - char *rdrpath; - char **env_fork; -} t_com; + char **argv; + char **env_fork; + char *rdrpath; + char *bin; + int32_t rdrfd; + int8_t redir; +} t_com; -struct s_lpipes +struct s_lpipes { - struct s_com *com; - struct s_lpipes *next; + struct s_com *com; + struct s_lpipes *next; }; /* @@ -57,26 +66,29 @@ struct s_lpipes ** 2: || */ -typedef struct s_line +typedef struct s_line_block { - uint8_t nextif; - struct s_com *com; - struct s_lpipes *pipes; - struct s_line *next; -} t_line; + char *lblock; + uint8_t nextif; + struct s_line_block *next; +} t_line_block; -typedef struct s_msh +typedef struct s_msh { - char **envp; - char ps[4][1024]; - uint8_t ret; - char *shname; - char **bu_ref; - char *cwd; - char env_fork_tmp[128][1024]; - uint8_t (*bu_ptr[FT_BUILTINS_COUNT])(char **, struct s_msh*); - struct s_line *curr; - struct s_lvars *vars; -} t_msh; + struct s_line_block *curr; + struct s_com *com; + struct s_lpipes *pipes; + struct s_lvars *vars; + struct s_lalias *alias; + char **envp; + char ps[4][1024]; + char env_fork_tmp[128][4096]; + char sqb_ref[FT_ID_SQB_COUNT][4]; + char *shname; + char *cwd; + int32_t fd; + uint8_t (*bu_ptr[FT_BUILTINS_COUNT])(char **, struct s_msh*); + uint8_t ret; +} t_msh; #endif diff --git a/src/u_alias.c b/src/u_alias.c new file mode 100644 index 0000000..14ca75e --- /dev/null +++ b/src/u_alias.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_alias.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <stddef.h> + +#include "d_define.h" +#include "s_lalias.h" +#include "s_struct.h" + +size_t + u_get_alias_value(char str[], const char name[], size_t dstsize, t_msh *msh) +{ + t_lalias *ptr; + + if (str != NULL) + { + str[0] = C_NUL; + } + ptr = msh->alias; + while (ptr != NULL && ft_strncmp(ptr->name, name, ft_strlen(name) + 1) != 0) + { + ptr = ptr->next; + } + if (ptr == NULL) + { + return (0); + } + if (str != NULL) + { + ft_strlcpy(str, ptr->val, dstsize); + } + return (ptr->id); +} + +void + u_set_alias_value(const char name[], const char value[], t_msh *msh) +{ + t_lalias *new; + + if (u_get_alias_value(NULL, name, 0, msh) != 0) + { + s_lalias_rebind(&msh->alias, name, value); + } + else + { + if ((new = s_lalias_new(name, value)) == NULL) + { + return ; + } + s_lalias_add_front(&msh->alias, new); + } +} diff --git a/src/u_alias.h b/src/u_alias.h new file mode 100644 index 0000000..59860db --- /dev/null +++ b/src/u_alias.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_alias.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef U_ALIAS_H +#define U_ALIAS_H + +#include <stddef.h> + +#include "s_struct.h" + +uint8_t u_get_alias_value(char str[], + const char name[], + size_t dstsize, + t_msh *msh); +void u_set_alias_value(const char name[], const char value[], t_msh *msh); + +#endif diff --git a/src/u_parse.c b/src/u_parse.c new file mode 100644 index 0000000..b49e6ba --- /dev/null +++ b/src/u_parse.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> + +#include "u_utils.h" +#include "d_define.h" + +t_quote_mode + u_meet_dquote(const char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE) + { + if (u_is_not_escaped(head, ptr) == TRUE) + { + return (Q_DOUBLE); + } + else + { + return (Q_NONE); + } + } + else if (mode == Q_DOUBLE && u_is_not_escaped(head, ptr) == TRUE) + { + return (Q_NONE); + } + return (mode); +} + +t_quote_mode + u_meet_squote(const char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE) + { + if (u_is_not_escaped(head, ptr) == TRUE) + { + return (Q_SINGLE); + } + else + { + return (Q_NONE); + } + } + else if (mode == Q_SINGLE) + { + return (Q_NONE); + } + return (mode); +} diff --git a/src/u_parse.h b/src/u_parse.h new file mode 100644 index 0000000..8542f80 --- /dev/null +++ b/src/u_parse.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_parse.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef U_PARSE_H +#define U_PARSE_H + +#include "d_define.h" + +t_quote_mode u_meet_dquote(const char *head, char *ptr, t_quote_mode mode); +t_quote_mode u_meet_squote(const char *head, char *ptr, t_quote_mode mode); + +#endif diff --git a/src/u_path.c b/src/u_path.c new file mode 100644 index 0000000..b43946f --- /dev/null +++ b/src/u_path.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_path.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stddef.h> +#include <dirent.h> +#include <limits.h> + +#include "s_struct.h" +#include "u_vars.h" + +static void u_get_fullpath(char fullpath[], + const char p_path[], + const char d_name[], + size_t dstsize) +{ + const size_t path_len = ft_strlen(p_path); + const size_t name_len = ft_strlen(d_name); + + fullpath[0] = C_NUL; + if (path_len + name_len < dstsize) + { + (void)ft_memcpy(fullpath, p_path, path_len); + *(fullpath + (path_len)) = '/'; + ft_memcpy(fullpath + path_len + 1, d_name, name_len); + *(fullpath + (path_len + name_len + 1)) = '\0'; + } +} + +uint8_t u_search_in_path(char fullpath[], + const char com[], + size_t dstsize, + t_msh *msh) +{ + struct dirent *ent; + char tmp[ARG_MAX]; + char *tok_path; + DIR *dir; + + if (u_get_var_value(tmp, "$PATH", ARG_MAX, msh) != 0) + return (1); + tok_path = ft_strtok(tmp, ":"); + while (tok_path != NULL) + { + if ((dir = opendir(tok_path)) != NULL) + { + while ((ent = readdir(dir)) != NULL) + { + if (ft_strncmp(com, ent->d_name, ft_strlen(com) + 1) == 0) + { + u_get_fullpath(fullpath, tok_path, ent->d_name, dstsize); + closedir(dir); + if (fullpath[0] == C_NUL) + return (1); + return (0); + } + } + closedir(dir); + } + tok_path = ft_strtok(NULL, ":"); + } + return (1); +} diff --git a/src/u_path.h b/src/u_path.h new file mode 100644 index 0000000..0c8e256 --- /dev/null +++ b/src/u_path.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* u_path.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef U_PATH_H +#define U_PATH_H + +#include <stdint.h> + +#include "s_struct.h" + +uint8_t u_search_in_path(char fullpath[], + const char com[], + size_t dstsize, + t_msh *msh); + +#endif diff --git a/src/u_utils.c b/src/u_utils.c index 745b79c..3d84be3 100644 --- a/src/u_utils.c +++ b/src/u_utils.c @@ -18,24 +18,32 @@ #include <term.h> #include <curses.h> +#include "d_define.h" #include "f_fail.h" #include "s_struct.h" -void -u_eof_stdin(void) +t_bool u_is_not_escaped(const char *head, const char *ptr) +{ + if (((ptr - head) == 0) || + ((ptr - head) >= 1 && *(ptr - 1) != C_BACKS) || + ((ptr - head) > 1 && *(ptr - 1) == C_BACKS && *(ptr - 2) == C_BACKS)) + return (TRUE); + return (FALSE); +} + +void u_eof_fd(int32_t fd) { char *line; - close(STDIN_FILENO); - get_next_line(STDIN_FILENO, &line); + close(fd); + get_next_line(fd, &line); ft_memdel((void*)&line); } -char - **u_get_env_var_names(t_msh *msh) +char **u_get_env_var_names(t_msh *msh) { - size_t i; char **vars; + size_t i; i = 0; while (msh->envp[i] != NULL) @@ -56,15 +64,31 @@ char return (vars); } -uint64_t - u_builtins_get_argc(const char *args[]) +uint64_t u_builtins_get_argc(const char *args[]) { uint64_t argc; argc = 0; - while (args[argc]) + while (args[argc] != NULL) { argc++; } return (argc); } + +uint8_t u_get_builtin_id(const char bin[]) +{ + char tmp[M_BUILTINS_REF_LEN]; + char *tok; + uint8_t i; + + i = 0; + ft_strlcpy(tmp, M_BUILTINS_REF, M_BUILTINS_REF_LEN); + tok = ft_strtok(tmp, ":"); + while (tok != NULL && ft_strncmp(bin, tok, ft_strlen(tok) + 1) != 0) + { + tok = ft_strtok(NULL, ":"); + i++; + } + return (i); +} diff --git a/src/u_utils.h b/src/u_utils.h index 6362e14..496f50e 100644 --- a/src/u_utils.h +++ b/src/u_utils.h @@ -13,10 +13,15 @@ #ifndef U_UTILS_H #define U_UTILS_H +#include <libft.h> #include <stdint.h> -void u_eof_stdin(void); +#include "s_struct.h" + +t_bool u_is_not_escaped(const char *head, const char *ptr); +void u_eof_fd(int32_t fd); uint64_t u_builtins_get_argc(const char *args[]); char **u_get_env_var_names(t_msh *msh); +uint8_t u_get_builtin_id(const char bin[]); #endif diff --git a/src/u_vars.c b/src/u_vars.c index 9594036..97fc580 100644 --- a/src/u_vars.c +++ b/src/u_vars.c @@ -21,26 +21,11 @@ #include "s_struct.h" #include "u_utils.h" -static char - *u_dup_env(char *p_env, - t_msh *msh) -{ - char *varval; - - if (!(varval = ft_strdup(p_env))) - { - f_alloc_and_destroy_msh(msh); - } - return (varval); -} - -static char - *u_get_frm_env(const char varname[], - t_msh *msh) +static void + u_get_frm_env(char str[], const char varname[], size_t dstsize, t_msh *msh) { char **env_dup; char *pp_env; - char *varval; size_t i; env_dup = u_get_env_var_names(msh); @@ -54,47 +39,38 @@ static char pp_env += 1; if (*pp_env == '=') pp_env += 1; - varval = u_dup_env(pp_env, msh); + ft_strlcpy(str, pp_env, dstsize); ft_delwords(env_dup); - return (varval); + return ; } i++; } ft_delwords(env_dup); - return (NULL); } -static char - *u_get_special_var(const char varname[], +static void + u_get_special_var(char str[], + const char varname[], + size_t dstsize, t_msh *msh) { - char *varval; - if (ft_strncmp(varname, FT_RET_VAR, 3) == 0) { - if ((varval = ft_uitoa(msh->ret)) == NULL) - { - f_alloc_and_destroy_msh(msh); - } - return (varval); + ft_strlcpy(str, ft_uitoa(msh->ret), 4); } else if (ft_strncmp(varname, FT_ZER_VAR, 3) == 0) { - if ((varval = ft_strdup(msh->shname)) == NULL) - { - f_alloc_and_destroy_msh(msh); - } - return (varval); + ft_strlcpy(str, msh->shname, dstsize); } - return (NULL); } -char - *u_get_cstm_vr(const char varname[], - t_msh *msh) +void + u_get_custom_var(char str[], + const char varname[], + size_t dstsize, + t_msh *msh) { t_lvars *ptr; - char *varval; ptr = msh->vars; while (ptr != NULL && @@ -104,51 +80,44 @@ char } if (ptr != NULL) { - if (!(varval = ft_strdup(ptr->val))) - { - f_alloc_and_destroy_msh(msh); - } - return (varval); - } - else - { - return (NULL); + ft_strlcpy(str, ptr->val, dstsize); } } /* -** char* -** u_get_var_value(const char varname[], t_msh *msh); +** void +** u_get_var_value(char str[], const char varname[], size_t dstsize, t_msh *msh) ** ** DESCRIPTION -** The u_get_var_value() function returns -** a heap-allocated, null-terminated string -** that may later be free'd containing the -** value of the variable varname[] including -** the '$' prefix. NULL is returned if varname[] -** wasn't found. +** The u_get_var_value() function fills +** str[] with a null-terminated string +** containing the value of the variable varname[] +** including the '$' prefix, in a similar way as +** sprintf does. No more than dstsize bytes will be +** copied into str[]. str[0] is set to \000 if +** varname[] wasn't found. */ -char - *u_get_var_value(const char varname[], - t_msh *msh) +uint8_t u_get_var_value(char str[], + const char varname[], + size_t dstsize, + t_msh *msh) { - /* TODO: check behaviour on empty vars -> "QWE=" */ - char *varval; - - varval = NULL; - if ((varval = u_get_special_var(varname, msh)) != NULL) + str[0] = C_NUL; + u_get_special_var(str, varname, dstsize, msh); + if (str[0] != C_NUL) { - return (varval); + return (0); } - else if ((varval = u_get_cstm_vr(varname, msh)) != NULL) + u_get_custom_var(str, varname, dstsize, msh); + if (str[0] != C_NUL) { - return (varval); + return (0); } - else + u_get_frm_env(str, varname, dstsize, msh); + if (str[0] != C_NUL) { - varval = u_get_frm_env(varname, msh); - return (varval); + return (0); } - return (NULL); + return (1); } diff --git a/src/u_vars.h b/src/u_vars.h index 0d83b4b..c76518e 100644 --- a/src/u_vars.h +++ b/src/u_vars.h @@ -13,9 +13,18 @@ #ifndef U_VARS_H #define U_VARS_H +#include <stdint.h> +#include <stddef.h> + #include "s_struct.h" -char *u_get_cstm_vr(const char varname[], t_msh *msh); -char *u_get_var_value(const char varname[], t_msh *msh); +void u_get_custom_var(char str[], + const char varname[], + size_t dstsize, + t_msh *msh); +uint8_t u_get_var_value(char str[], + const char varname[], + size_t dstsize, + t_msh *msh); #endif diff --git a/src/u_vars_next.c b/src/u_vars_next.c index c6c351b..2f23667 100644 --- a/src/u_vars_next.c +++ b/src/u_vars_next.c @@ -13,15 +13,16 @@ #include <libft.h> #include <inttypes.h> #include <stdlib.h> +#include <limits.h> #include "d_enum.h" #include "s_lvars.h" #include "s_struct.h" +#include "u_parse.h" #include "u_utils.h" static int64_t - u_get_env_var_line(const char varname[], - t_msh *msh) + u_get_env_var_line(const char varname[], t_msh *msh) { char **env_dup; int64_t i; @@ -42,8 +43,7 @@ static int64_t } static t_bool - u_get_custom_var_existance(const char varname[], - t_msh *msh) + u_get_custom_var_existance(const char varname[], t_msh *msh) { t_lvars *ptr; @@ -63,6 +63,11 @@ static t_bool } } +/* static void */ +/* u_newval_subst(char newval_subst[], const char newval[]) */ +/* { */ +/* } */ + /* ** void ** u_subst_var_value(const char varname[], const char newval[], t_msh *msh); @@ -70,23 +75,22 @@ static t_bool ** DESCRIPTION ** The subst_var_value() changes the value of msh->envp ** variable varname[] with newval[]. If varname[] wasn't found -** in msh->envp, varname[] is searched in msh->vars. +** in msh->envp, varname[] is searched in msh->vars. Otherwise +** varname[] is added to msh->vars. */ void - u_subst_var_value(const char varname[], - const char newval[], - t_msh *msh) + u_subst_var_value(const char varname[], const char newval[], t_msh *msh) { - char new_line_fmt[2048]; + char new_line_fmt[ARG_MAX]; int64_t env_line; if ((env_line = u_get_env_var_line(varname + 1, msh)) > -1) { ft_memdel((void*)&msh->envp[env_line]); ft_sprintf(new_line_fmt, "%s=%s", varname + 1, newval); - if (!(msh->envp[env_line] = - (char*)malloc((ft_strlen(new_line_fmt) + 1) * sizeof(char)))) + if ((msh->envp[env_line] = (char*)malloc((ft_strlen(new_line_fmt) + 1) * + sizeof(char))) == NULL) { /* TODO: Handle this fail */ } |