diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-08-19 16:37:13 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-08-19 16:37:13 +0200 |
| commit | 957434ecd3c8170aafc145263b0090863ceadba3 (patch) | |
| tree | 5a218179d7c282a87564dbf6eb89beb603c3385b | |
| parent | e77b1667e23a05f2874f80f5e47e634c58180c37 (diff) | |
| download | minishell-957434ecd3c8170aafc145263b0090863ceadba3.tar.gz minishell-957434ecd3c8170aafc145263b0090863ceadba3.tar.bz2 minishell-957434ecd3c8170aafc145263b0090863ceadba3.zip | |
Removing glob, Rewritting preprocessing with escape and interpolation only
| -rw-r--r-- | include/lexer.h | 19 | ||||
| -rw-r--r-- | include/ms_glob.h | 36 | ||||
| m--------- | minishell_test | 0 | ||||
| -rw-r--r-- | print_argv_env_main.c | 12 | ||||
| -rw-r--r-- | src/env.c | 4 | ||||
| -rw-r--r-- | src/eval/utils_eval.c | 54 | ||||
| -rw-r--r-- | src/lexer/token.c | 28 | ||||
| -rw-r--r-- | src/main.c | 8 | ||||
| -rw-r--r-- | src/ms_glob.c | 185 | ||||
| -rw-r--r-- | src/preprocess.c | 246 |
10 files changed, 169 insertions, 423 deletions
diff --git a/include/lexer.h b/include/lexer.h index f40db56..27910a5 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -6,7 +6,7 @@ /* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/19 10:51:26 by nahaddac #+# #+# */ -/* Updated: 2020/07/20 11:07:13 by nahaddac ### ########.fr */ +/* Updated: 2020/08/19 13:41:08 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,13 +53,24 @@ int lexer_sep(char input); int lexer_verif_entre_cote(char *input, int i); int lexe_space(char *input); + +t_token *push_token_enum(t_token *lst_token); + +t_ftlst *lexe_trim_out(t_ftlst *lst); + +/* +** token.c +*/ + t_token *token_new(enum e_token_tag tag, char *content); t_token *token_new_until(enum e_token_tag tag, char *content, int n); void token_destroy(t_token *token); void token_destroy_lst(t_ftlst *tokens); void token_destroy_lst2(t_ftlst *tokens1, t_ftlst *tokens2); -t_token *push_token_enum(t_token *lst_token); - -t_ftlst *lexe_trim_out(t_ftlst *lst); +enum e_token_tag token_tag(t_ftlst *token_lst); +void token_set_tag(t_ftlst *token_lst, enum e_token_tag tag); +char *token_content(t_ftlst *token_lst); +void token_set_content(t_ftlst *token_lst, char *content); +void token_set_contentf(t_ftlst *token_lst, char *content); #endif diff --git a/include/ms_glob.h b/include/ms_glob.h deleted file mode 100644 index e340c45..0000000 --- a/include/ms_glob.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ms_glob.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/04/05 11:45:11 by charles #+# #+# */ -/* Updated: 2020/07/15 12:12:22 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef MS_GLOB_H -# define MS_GLOB_H - -# include <dirent.h> -# include <unistd.h> -# include <stddef.h> -# include <limits.h> - -# include "libft_str.h" -# include "libft_vec.h" - -# include "minishell.h" - -struct s_glob_param -{ - char *pattern; - t_ftvec *matches; -}; - -t_ftvec *glob_matches(char *pattern); -char *ms_glob(char *pattern); -char *ms_globf(char *pattern); - -#endif diff --git a/minishell_test b/minishell_test -Subproject a90b8ed1561e1edd05e2689e566727acedf4ff6 +Subproject cae6075853516fba08b61f42fa9f25f4afd1df1 diff --git a/print_argv_env_main.c b/print_argv_env_main.c index 4011275..330638c 100644 --- a/print_argv_env_main.c +++ b/print_argv_env_main.c @@ -4,13 +4,13 @@ int main(int argc, char **argv, char **envp) { - char buf[PATH_MAX]; + /* char buf[PATH_MAX]; */ - getcwd(buf, PATH_MAX); - printf("%s\n", buf); - /* printf("ARGV:\n"); */ - /* for (int i = 0; i < argc; i++) */ - /* printf("[%d] %s\n", i, argv[i]); */ + /* getcwd(buf, PATH_MAX); */ + /* printf("%s\n", buf); */ + printf("ARGV:\n"); + for (int i = 0; i < argc; i++) + printf("[%d] %s\n", i, argv[i]); /* printf("\nENV:\n"); */ /* for (int i = 0; envp[i] != NULL && i < 10; i++) */ /* printf("[%d] %s\n", i, envp[i]); */ @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/07/16 08:44:28 by charles ### ########.fr */ +/* Updated: 2020/08/19 10:23:55 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -97,6 +97,8 @@ char *env_search_first_match(t_env env, const char *haystack) size_t i; size_t key_len; + if (!ft_isalnum(*haystack) && *haystack != '_' && *haystack != '?') // $ alone + return ("$"); if (ft_isdigit(*haystack)) return (NULL); len = 0; diff --git a/src/eval/utils_eval.c b/src/eval/utils_eval.c deleted file mode 100644 index 5fefe70..0000000 --- a/src/eval/utils_eval.c +++ /dev/null @@ -1,54 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* utils_eval.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/07/20 13:07:25 by nahaddac #+# #+# */ -/* Updated: 2020/07/20 17:53:18 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "eval.h" - - -t_ftlst *split_token(t_ftlst **lst, enum e_token_tag tag) -{ - t_ftlst *curr; - t_ftlst *start; - enum e_token_tag curr_tag; - - start = *lst; - curr = *lst; - t_ftlst *prev = curr; - while (curr != NULL) - { - curr_tag = ((t_token *)curr->data)->tag; - if (!(curr_tag & TAG_STICK) || !(curr_tag & TAG_IS_STR)) - { - *lst = prev->next; - prev->next = NULL; - return start; - } - prev = curr; - curr = curr->next; - } - return start; - - - - /* if (curr != NULL) */ - /* curr_tag = ((t_token *)curr->data)->tag; */ - /* while (curr != NULL && curr_tag & TAG_STICK && curr_tag & TAG_IS_STR) */ - /* { */ - /* curr = curr->next; */ - /* curr_tag = ((t_token *)curr->data)->tag; */ - /* if (curr == NULL || !(curr_tag & TAG_STICK) || !(curr_tag & TAG_IS_STR)) */ - /* { */ - /* *lst = curr->next; */ - /* curr->next = NULL; */ - /* } */ - /* } */ - /* return start; */ -} diff --git a/src/lexer/token.c b/src/lexer/token.c index f7c1691..43971de 100644 --- a/src/lexer/token.c +++ b/src/lexer/token.c @@ -6,7 +6,7 @@ /* By: charles <charles@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/09 13:38:08 by charles #+# #+# */ -/* Updated: 2020/07/13 09:58:18 by nahaddac ### ########.fr */ +/* Updated: 2020/08/19 13:40:55 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -55,3 +55,29 @@ void token_destroy_lst2(t_ftlst *tokens1, t_ftlst *tokens2) ft_lstdestroy(&tokens1, (void (*)(void*))token_destroy); ft_lstdestroy(&tokens2, (void (*)(void*))token_destroy); } + +enum e_token_tag token_tag(t_ftlst *token_lst) +{ + return (((t_token*)token_lst->data)->tag); +} + +void token_set_tag(t_ftlst *token_lst, enum e_token_tag tag) +{ + ((t_token*)token_lst->data)->tag = tag; +} + +char *token_content(t_ftlst *token_lst) +{ + return (((t_token*)token_lst->data)->content); +} + +void token_set_content(t_ftlst *token_lst, char *content) +{ + ((t_token*)token_lst->data)->content = content; +} + +void token_set_contentf(t_ftlst *token_lst, char *content) +{ + free(token_content(token_lst)); + token_set_content(token_lst, content); +} @@ -6,7 +6,7 @@ /* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/07/20 17:35:51 by charles ### ########.fr */ +/* Updated: 2020/08/19 10:03:24 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -75,9 +75,9 @@ int main(int argc, char **argv, char **envp) // env_export(env, "_", env_exec_path); g_last_status_code = 0; - signal(SIGINT, signal_sigint); - signal(SIGQUIT, signal_sigquit); - signal(SIGTERM, signal_sigterm); + /* signal(SIGINT, signal_sigint); */ + /* signal(SIGQUIT, signal_sigquit); */ + /* signal(SIGTERM, signal_sigterm); */ char *last_slash = ft_strrchr(argv[0], '/'); if (last_slash == NULL) diff --git a/src/ms_glob.c b/src/ms_glob.c deleted file mode 100644 index 059ff1c..0000000 --- a/src/ms_glob.c +++ /dev/null @@ -1,185 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ms_glob.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/04/05 11:44:07 by charles #+# #+# */ -/* Updated: 2020/07/20 17:14:04 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "ms_glob.h" - -/* -** \brief Match vector start size -** \note From ~: average file in directory is 8 -** From /: average file in directory is 15 -*/ - -#define MATCHES_VEC_START_SIZE 16 - -static char g_glob_path[PATH_MAX]; - -/* -** \brief Glob directory iteration function -** for subdirectory matches -** \param dirname Current directory name -** \param entry Current directory entry -** \param param Contain matches vector and pattern to match -** \param subdir_pattern Pattern left after '/' in parrent pattern -** \return 0 on success, -1 on error -*/ - -static int glob_iter_subdir( - struct dirent *entry, - struct s_glob_param *param, - char *subdir_pattern -) -{ - t_ftvec *subdir_matches; - size_t i; - - subdir_matches = glob_matches(subdir_pattern); - if (subdir_matches == NULL) - return (-1); - i = 0; - while (i < subdir_matches->size) - if (ft_vecpush_safe(param->matches, ft_strjoin3(entry->d_name, - "/", subdir_matches->data[i++])) == NULL) - { - ft_vecdestroy(subdir_matches, free); - return (-1); - } - ft_vecdestroy(subdir_matches, free); - subdir_pattern[-1] = '/'; - return (0); -} - -/* -** \brief Glob directory iteration function -** \param dirname Current directory name -** \param entry Current directory entry -** \param param Contain matches vector and pattern to match -** \return 0 on success or -1 on error -*/ - -static int glob_iter( - char *dirname, - struct dirent *entry, - struct s_glob_param *param -) -{ - char *subdir_pattern; - int ret; - - (void)dirname; - if (param->pattern[0] != '.' && entry->d_name[0] == '.') - return (0); - if ((subdir_pattern = ft_strchr(param->pattern, '/')) != NULL) - *subdir_pattern++ = '\0'; - if (!ft_fnmatch(param->pattern, entry->d_name)) - { - if (subdir_pattern != NULL) - subdir_pattern[-1] = '/'; - return (0); - } - if (subdir_pattern != NULL) - { - if (entry->d_type != DT_DIR && entry->d_type != DT_LNK) - { - subdir_pattern[-1] = '/'; - return (0); - } - ft_strcat3(g_glob_path, "/", entry->d_name); - ret = glob_iter_subdir(entry, param, subdir_pattern); - *ft_strrchr(g_glob_path, '/') = '\0'; - return (ret); - } - if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) - return (-1); - return (0); -} - -/* -** \brief Fill a vector with all match -** \param pattern Pattern to match -** \return Matches vector or NULL on error -*/ - -t_ftvec *glob_matches(char *pattern) -{ - struct s_glob_param param; - - param.pattern = pattern; - if ((param.matches = ft_vecnew(MATCHES_VEC_START_SIZE)) == NULL) - return (NULL); - if (utils_directory_iter(g_glob_path, ¶m, (t_directory_iter_func)glob_iter) == -1) - { - ft_vecdestroy(param.matches, free); - return (NULL); - } - return (param.matches); -} - -/* -** \brief Search files which match a pattern in the current directory -** \param pattern Pattern to match -** \return Space separated list of match, -** pattern if no match found, -** NULL on error -*/ - -char *ms_glob(char *pattern) -{ - char *join; - t_ftvec *matches; - bool absolute; - size_t i; - - absolute = *pattern == '/'; - if (absolute) - ft_strcpy(g_glob_path, "/"); - else if (getcwd(g_glob_path, PATH_MAX) == NULL) - return (NULL); - if ((matches = glob_matches(absolute ? pattern + 1 : pattern)) == NULL) - return (NULL); - if (absolute) - { - i = -1; - while (++i < matches->size) - if ((matches->data[i] = ft_strjoinf("/", matches->data[i], FT_STRJOINF_SND)) == NULL) - { - ft_vecdestroy(matches, free); - return (NULL); - } - } - ft_vecsort(matches, ft_compar_str); - if (ft_vecpush(matches, NULL) == NULL || - (join = ft_strsjoin((char**)matches->data, " ")) == NULL) - { - ft_vecdestroy(matches, free); - return (NULL); - } - ft_vecdestroy(matches, free); - if (*join == '\0') - { - free(join); - return (ft_strdup(pattern)); - } - return (join); -} - -/* -** \brief Wrapper around `ms_glob` which free `pattern` for convenience -*/ - -char *ms_globf(char *pattern) -{ - char *ret; - - ret = ms_glob(pattern); - free(pattern); - return (ret); -} diff --git a/src/preprocess.c b/src/preprocess.c index c9fbd8a..b3cb493 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,175 +6,157 @@ /* By: charles <charles@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/07/20 17:36:09 by charles ### ########.fr */ +/* Updated: 2020/08/19 16:32:22 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -#include "ms_glob.h" #include "lexer.h" #include "eval.h" -static bool st_escapable(char c, enum e_token_tag tag) -{ - if (tag & TAG_STR) - return (true); - if ((tag & TAG_STR_DOUBLE) && (c == '\\' || c == '"' || c == '$')) - return (true); - return (false); -} - -static char *st_iterpolate_env(char *str, enum e_token_tag tag, t_env env) -{ - size_t i; - t_ftdstr *dstr; - char *match; - - if ((dstr = ft_dstrwrap(str)) == NULL) - return (NULL); - i = -1; - while (++i < dstr->length) - if (dstr->str[i] == '\\' && st_escapable(dstr->str[i + 1], tag)) - ft_dstrerase(dstr, i, 1); - else if (dstr->str[i] == '$' && !ft_isalnum(dstr->str[i + 1]) - && dstr->str[i + 1] != '_' - && dstr->str[i + 1] != '?') // $ alone - continue; - else if (dstr->str[i] == '$') - { - if ((match = env_search_first_match(env, dstr->str + i + 1)) == NULL) - { - ft_dstrerase(dstr, i, utils_var_end(dstr->str + i + 1)); - i--; - } - else - { - if (ft_dstrsubstitute(dstr, match, i, utils_var_end(dstr->str + i + 1)) == NULL) - { - ft_dstrdestroy(dstr); - return (NULL); - } - i += ft_strlen(match) - 1; - } - } - return (ft_dstrunwrap(dstr)); -} - -static char *st_iterpolate_globs(char *str) +static t_ftlst *st_field_split(char *str) { char **strs; + t_ftlst *ret; + t_ftlst *node; int i; - if ((strs = ft_splitf(str, ' ')) == NULL) + if ((strs = ft_split(str, ' ')) == NULL) return (NULL); + ret = NULL; i = 0; while (strs[i] != NULL) { - if (ft_strchr(strs[i], '*') != NULL - && (strs[i] = ms_globf(strs[i])) == NULL) + if ((node = ft_lstnew(token_new(TAG_STR, strs[i]))) == NULL) { - ft_split_destroy(strs); + free(strs); return (NULL); } + ft_lstpush_back(&ret, node); i++; } - return (ft_strsjoinf(strs, " ")); -} - -static int st_splat_arg(t_ftvec *argv, int i) -{ - t_token *splated; - char **strs; - int j; - - if ((splated = ft_vectake(argv, i)) == NULL - || (strs = ft_split(splated->content, ' ')) == NULL) - { - token_destroy(splated); - return (-1); - } - j = 0; - while (strs[j] != NULL) - { - if (ft_vecinsert_safe(argv, i + j, token_new(TAG_STR, strs[j])) == NULL) - { - token_destroy(splated); - ft_split_destroy(strs); - return (-1); - } - j++; - } - token_destroy(splated); - ft_split_destroy(strs); - return (i + j - 1); -} - -static void st_iter_func_unwrap_token(void **addr) -{ - char *content; - - content = (*(t_token**)addr)->content; - free(*(t_token**)addr); - *(char**)addr = content; + free(strs); + return (ret); } -// need to free argv on error char **preprocess(t_ftlst **tokens, t_env env) { - size_t i; - t_token *token; - t_ftvec *argv; + t_ftlst *curr; - if ((argv = ft_vecfrom_lst(*tokens)) == NULL) - { - ft_lstdestroy(tokens, NULL); - return (NULL); - } - ft_lstdestroy(tokens, NULL); - i = -1; - while (++i < argv->size) + curr = *tokens; + while (curr != NULL) { - token = argv->data[i]; - /* printf("|%s| %d\n", token->content, token->tag & TAG_STICK); */ - if (token->tag & TAG_STR_SINGLE) - continue ; - token->content = st_iterpolate_env(token->content, token->tag, env); - if (token->tag & TAG_STR) + if (token_tag(curr) & (TAG_STR | TAG_STR_DOUBLE)) { - if (ft_strchr(token->content, '*') != NULL) - token->content = st_iterpolate_globs(token->content); - if (ft_strchr(token->content, ' ') != NULL) + char *str = token_content(curr); + + size_t i = -1; + while (str[++i] != '\0') { - if ((i = st_splat_arg(argv, i)) == (size_t)-1) - return (NULL); - if (token->tag & TAG_STICK) // FIXME temporary will not work with `echo *''` - ((t_token*)argv->data[i])->tag |= TAG_STICK; + str = token_content(curr); + // escape + if (str[i] == '\\' + && (token_tag(curr)& TAG_STR + || ((token_tag(curr) & TAG_STR_DOUBLE) && ft_strchr("\\\"$", str[i + 1])))) + { + ft_memmove(&str[i], &str[i + 1], ft_strlen(&str[i + 1]) + 1); + continue; + } + + // interpolate + if (str[i] == '$') + { + char *match; + size_t var_len = utils_var_end(&str[i + 1]); + + if ((match = env_search_first_match(env, &str[i + 1])) == NULL) + { + ft_memmove(&str[i], &str[i + var_len], var_len ); + i--; + continue; + } + + char *before; + char *after; + size_t len; + + str[i] = '\0'; + before = str; + after = &str[i + var_len]; + /* printf("%s | %s | %s\n", before, match, after); */ + if (token_tag(curr) & TAG_STR) + { + t_ftlst *fields = st_field_split(match); + /* printf("f %p\n", fields); */ + /* printf("f %s\n", token_content(fields)); */ + + len = ft_strlen(token_content(ft_lstlast(fields))); + /* printf("l %d\n", len); */ + + if (fields->next == NULL) + { + /* printf("yo\n"); */ + token_set_content(curr, ft_strjoin3(before, token_content(fields), after)); + } + else + { + token_set_content(curr, ft_strjoin(before, token_content(fields))); + token_set_content(ft_lstlast(fields), + ft_strjoin(token_content(ft_lstlast(fields)), after)); + t_ftlst *tmp = curr->next; + curr->next = fields->next; + curr = ft_lstlast(fields); + curr->next = tmp; + } + /* str = token_content(curr); */ + /* i = len - 1; */ + /* printf("%d\n", i); */ + i += len - 1; + /* printf("%d\n", i); */ + /* printf("> %s\n", str); */ + /* printf(">> %s\n", str + i); */ + } + else if (token_tag(curr) & TAG_STR_DOUBLE) + { + token_set_content(curr, ft_strjoin3(before, match, after)); + /* printf(">%s< %d\n", match, ft_strlen(match)); */ + i += ft_strlen(match) - 1; + /* printf("> %zu %s\n", i, str); */ + } + } } } + curr = curr->next; } - /* printf("-------\n"); */ - t_token *next; - i = -1; - while (++i < argv->size - 1) + curr = *tokens; + while (curr != NULL) { - token = argv->data[i]; - /* printf("|%s| %d\n", token->content, token->tag & TAG_STICK); */ - while (token->tag & TAG_STICK && i + 1 < argv->size) + // curr->next shouldn't be null + if (token_tag(curr) & TAG_STICK) { - /* printf("2|%s|\n", token->content); */ - next = argv->data[i + 1]; - token->content = ft_strjoinf_fst(token->content, next->content); - if (token->content == NULL) - return (NULL); - token->tag &= next->tag; - ft_vecremove(argv, i + 1, (void (*)(void*))token_destroy); + token_set_content(curr, ft_strjoinf_fst(token_content(curr), token_content(curr->next))); + t_ftlst *tmp = curr->next->next; + token_set_tag(curr, token_tag(curr->next)); + ft_lstdelone(curr->next, free); + curr->next = tmp; + continue; } + curr = curr->next; } - ft_veciter_addr(argv, st_iter_func_unwrap_token); - ft_vecpush(argv, NULL); - return ((char**)ft_vecunwrap(argv)); + char **ret = malloc(sizeof(char*) * (ft_lstsize(*tokens) + 1)); + curr = *tokens; + size_t i = 0; + while (curr != NULL) + { + ret[i] = token_content(curr); + i++; + curr = curr->next; + } + ret[i] = NULL; + ft_lstdestroy(tokens, NULL); + return ret; } // need to free tokens |
