aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2020-08-19 16:37:13 +0200
committerCharles Cabergs <me@cacharle.xyz>2020-08-19 16:37:13 +0200
commit957434ecd3c8170aafc145263b0090863ceadba3 (patch)
tree5a218179d7c282a87564dbf6eb89beb603c3385b /src
parente77b1667e23a05f2874f80f5e47e634c58180c37 (diff)
downloadminishell-957434ecd3c8170aafc145263b0090863ceadba3.tar.gz
minishell-957434ecd3c8170aafc145263b0090863ceadba3.tar.bz2
minishell-957434ecd3c8170aafc145263b0090863ceadba3.zip
Removing glob, Rewritting preprocessing with escape and interpolation only
Diffstat (limited to 'src')
-rw-r--r--src/env.c4
-rw-r--r--src/eval/utils_eval.c54
-rw-r--r--src/lexer/token.c28
-rw-r--r--src/main.c8
-rw-r--r--src/ms_glob.c185
-rw-r--r--src/preprocess.c246
6 files changed, 148 insertions, 377 deletions
diff --git a/src/env.c b/src/env.c
index 589c83e..a80797f 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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);
+}
diff --git a/src/main.c b/src/main.c
index 3e23206..27dae1b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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, &param, (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