vars.c \
input_handling.c \
wildcards.c \
+ wildcards_inner.c \
+ wildcards_helpers.c \
tokenization.c \
+ token_categorize.c \
+ token_finish.c \
parsing.c \
execution.c \
helpers.c \
+ vars_helpers.c \
\
builtins/cd.c \
builtins/echo.c \
/* ::: :::::::: */
/* minishell.h :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/02 13:22:57 by ljiriste #+# #+# */
-/* Updated: 2024/08/31 11:59:16 by ljiriste ### ########.fr */
+/* Updated: 2024/08/31 16:23:06 by lnikolov ### ########.fr */
/* */
/* ************************************************************************** */
# include "libft.h"
# include <signal.h>
+enum token_types
+{
+ WORD,
+ ASSIGNMENT_WORD,
+ IO_NUMBER,
+ AND_IF,
+ OR_IF,
+ LESS,
+ GREAT,
+ DLESS,
+ DGREAT,
+ PIPE,
+ LPARA,
+ RPARA,
+};
+
extern volatile sig_atomic_t g_last_signal;
void handler(int sig_num);
void unquote_field(char *field);
int add_word(t_vec *exp_str, const char *word, const t_execution_env *env, int quote);
int add_conformant(t_vec *expanded, t_wildcard_info *info, char quote);
+int should_be_expanded(const char *word);
int expand_dir(t_vec *expanded, t_wildcard_info *info);
int expand_wildcards(char **input, const t_execution_env *env);
+char *get_start_path(const char *str, const t_execution_env *env);
+int replace_str_by_joint_quoted_split(char **str, char **expanded_split);
+int replace_str_by_joint_split(char **str, char **expanded_split);
+
int tokenize(char *line, t_vec *tokens);
int parse(t_vec *tokens, t_tree **parse_tree);
int execute(t_tree *parse_tree, t_execution_env *env);
-
-char **quoted_split(const char *str);
-
+int finish_token(t_vec *tokens, t_vec *current_token, char next);
+char **quoted_split(const char *str);
+int categorization_step(char *line, size_t *i, t_vec *current_token, t_vec *tokens);
+int handle_quote(t_vec *current_token, char *line, char quote_char, size_t *i);
#endif // MINISHELL_H
/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/26 09:08:46 by ljiriste #+# #+# */
-/* Updated: 2024/08/31 14:29:55 by lnikolov ### ########.fr */
+/* Updated: 2024/08/31 15:46:32 by lnikolov ### ########.fr */
/* */
/* ************************************************************************** */
const char *get_var_value(const t_vec *vars, const char *var_name);
const char *get_env_var_value(const t_execution_env *env, const char *var_name);
char *get_var_name(const char *line);
+int add_var_line(t_vec *vec, const char *line);
void free_str(void *str);
void free_token(void *token);
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* tokens.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/08/31 15:41:11 by lnikolov #+# #+# */
+/* Updated: 2024/08/31 15:42:19 by lnikolov ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef TOKENS_H
+# define TOKENS_H
+
+static const char *g_tokens[12] = {
+ "WORD",
+ "ASSIGNMENT_WORD",
+ "IO_NUMBER",
+ "AND_IF",
+ "OR_IF",
+ "LESS",
+ "GREAT",
+ "DLESS",
+ "DGREAT",
+ "PIPE",
+ "LPARA",
+ "RPARA"};
+
+#endif
\ No newline at end of file
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* categorization_step.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/06/21 16:34:43 by ljiriste #+# #+# */
+/* Updated: 2024/08/31 15:53:33 by lnikolov ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include <stdlib.h>
+
+static int is_operator_start(char *str, size_t size)
+{
+ if (!str)
+ return (1);
+ return (!ft_strncmp(str, "&&", size)
+ || !ft_strncmp(str, "||", size)
+ || !ft_strncmp(str, "<", size)
+ || !ft_strncmp(str, ">", size)
+ || !ft_strncmp(str, "<<", size)
+ || !ft_strncmp(str, ">>", size)
+ || !ft_strncmp(str, "|", size)
+ || !ft_strncmp(str, "(", size)
+ || !ft_strncmp(str, ")", size));
+}
+
+static int is_operator(t_vec *current_token)
+{
+ char *str;
+ int res;
+
+ ft_vec_append(current_token, "");
+ str = current_token->vec;
+ res = (!ft_strcmp(str, "&&")
+ || !ft_strcmp(str, "||")
+ || !ft_strcmp(str, "<")
+ || !ft_strcmp(str, ">")
+ || !ft_strcmp(str, "<<")
+ || !ft_strcmp(str, ">>")
+ || !ft_strcmp(str, "|")
+ || !ft_strcmp(str, "(")
+ || !ft_strcmp(str, ")"));
+ ft_vec_erase(current_token, current_token->size - 1, NULL);
+ return (res);
+}
+
+static int can_expand_operator(t_vec *current_token, char c)
+{
+ int res;
+
+ ft_vec_append(current_token, &c);
+ res = is_operator_start(current_token->vec, current_token->size);
+ ft_vec_erase(current_token, current_token->size - 1, NULL);
+ return (res);
+}
+
+int categorization_step(char *line, size_t *i,
+ t_vec *current_token, t_vec *tokens)
+{
+ int res;
+
+ if (is_operator_start(current_token->vec, current_token->size)
+ && can_expand_operator(current_token, line[*i]))
+ res = (ft_vec_append(current_token, line + (*i)++) != success);
+ else if (is_operator(current_token))
+ res = finish_token(tokens, current_token, '\0');
+ else if (line[*i] == '\'')
+ res = handle_quote(current_token, line, '\'', i);
+ else if (line[*i] == '"' )
+ res = handle_quote(current_token, line, '"', i);
+ else if (is_operator_start(line + *i, 1) || ft_isspace(line[*i]))
+ {
+ if (current_token->size > 0)
+ res = finish_token(tokens, current_token, line[*i]);
+ if (!ft_isspace(line[*i]))
+ res = res || ft_vec_append(current_token, line + *i)
+ != success;
+ ++*i;
+ }
+ else if (current_token->size > 0)
+ res = ft_vec_append(current_token, line + (*i)++) != success;
+ else
+ res = ft_vec_append(current_token, line + (*i)++) != success;
+ return (res);
+}
+
+int handle_quote(t_vec *current_token, char *line,
+ char quote_char, size_t *i)
+{
+ if (ft_vec_append(current_token, line + (*i)++) != success)
+ return (1);
+ while (line[*i] != quote_char)
+ {
+ if (!line[*i])
+ return (1);
+ else
+ if (ft_vec_append(current_token, line + (*i)++) != success)
+ return (1);
+ }
+ ft_vec_append(current_token, line + (*i)++);
+ return (0);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* token_finish.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/08/31 15:12:50 by lnikolov #+# #+# */
+/* Updated: 2024/08/31 16:26:41 by lnikolov ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "tokens.h"
+#include "minishell.h"
+#include <stdlib.h>
+
+static int only_contains_digits(const char *str)
+{
+ while (ft_isdigit(*str))
+ ++str;
+ return (*str == '\0');
+}
+
+static const char *get_token_type(const char *str, char next)
+{
+ if (!ft_strcmp(str, "&&"))
+ return (g_tokens[AND_IF]);
+ if (!ft_strcmp(str, "||"))
+ return (g_tokens[OR_IF]);
+ if (!ft_strcmp(str, "<"))
+ return (g_tokens[LESS]);
+ if (!ft_strcmp(str, ">"))
+ return (g_tokens[GREAT]);
+ if (!ft_strcmp(str, "<<"))
+ return (g_tokens[DLESS]);
+ if (!ft_strcmp(str, ">>"))
+ return (g_tokens[DGREAT]);
+ if (!ft_strcmp(str, "|"))
+ return (g_tokens[PIPE]);
+ if (!ft_strcmp(str, "("))
+ return (g_tokens[LPARA]);
+ if (!ft_strcmp(str, ")"))
+ return (g_tokens[RPARA]);
+ if (is_assignment_word(str))
+ return (g_tokens[ASSIGNMENT_WORD]);
+ if (only_contains_digits(str) && (next == '<' || next == '>'))
+ return (g_tokens[IO_NUMBER]);
+ return (g_tokens[WORD]);
+}
+
+// This function turns the input char string into a string of tokens
+// It possibly should use ft_strdup(ft_vec_access(¤t_token, 0))
+// as that only relies on the consecutivness of memory of t_vec
+int finish_token(t_vec *tokens, t_vec *current_token, char next)
+{
+ t_token token;
+
+ if (ft_vec_append(current_token, "") != success)
+ return (1);
+ token.type = (char *)get_token_type(current_token->vec, next);
+ if (!token.type)
+ return (1);
+ token.str = current_token->vec;
+ if (ft_vec_append(tokens, &token) != success)
+ return (1);
+ return (ft_vec_init(current_token, sizeof(char)) != success);
+}
/* ::: :::::::: */
/* tokenization.c :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: lnikolov <lnikolov@student.42prague.com> +#+ +:+ +#+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
-/* Created: 2024/06/21 16:34:43 by ljiriste #+# #+# */
-/* Updated: 2024/08/31 12:55:57 by ljiriste ### ########.fr */
+/* Created: 2024/08/31 15:08:00 by lnikolov #+# #+# */
+/* Updated: 2024/08/31 15:42:59 by lnikolov ### ########.fr */
/* */
/* ************************************************************************** */
+#include "tokens.h"
#include "minishell.h"
#include <stdlib.h>
-static int is_operator_start(char *str, size_t size)
-{
- if (!str)
- return (1);
- return (!ft_strncmp(str, "&&", size)
- || !ft_strncmp(str, "||", size)
- || !ft_strncmp(str, "<", size)
- || !ft_strncmp(str, ">", size)
- || !ft_strncmp(str, "<<", size)
- || !ft_strncmp(str, ">>", size)
- || !ft_strncmp(str, "|", size)
- || !ft_strncmp(str, "(", size)
- || !ft_strncmp(str, ")", size));
-}
-
-static int is_operator(t_vec *current_token)
-{
- char *str;
- int res;
-
- ft_vec_append(current_token, "");
- str = current_token->vec;
- res = (!ft_strcmp(str, "&&")
- || !ft_strcmp(str, "||")
- || !ft_strcmp(str, "<")
- || !ft_strcmp(str, ">")
- || !ft_strcmp(str, "<<")
- || !ft_strcmp(str, ">>")
- || !ft_strcmp(str, "|")
- || !ft_strcmp(str, "(")
- || !ft_strcmp(str, ")"));
- ft_vec_erase(current_token, current_token->size - 1, NULL);
- return (res);
-}
-
-static int can_expand_operator(t_vec *current_token, char c)
-{
- int res;
-
- ft_vec_append(current_token, &c);
- res = is_operator_start(current_token->vec, current_token->size);
- ft_vec_erase(current_token, current_token->size - 1, NULL);
- return (res);
-}
-
-static const char *g_tokens[12] = {
- "WORD",
- "ASSIGNMENT_WORD",
- "IO_NUMBER",
- "AND_IF",
- "OR_IF",
- "LESS",
- "GREAT",
- "DLESS",
- "DGREAT",
- "PIPE",
- "LPARA",
- "RPARA"};
-
-enum token_types
-{
- WORD,
- ASSIGNMENT_WORD,
- IO_NUMBER,
- AND_IF,
- OR_IF,
- LESS,
- GREAT,
- DLESS,
- DGREAT,
- PIPE,
- LPARA,
- RPARA,
-};
-
-int only_contains_digits(const char *str)
-{
- while (ft_isdigit(*str))
- ++str;
- return (*str == '\0');
-}
-
-const char *get_token_type(const char *str, char next)
-{
- if (!ft_strcmp(str, "&&"))
- return (g_tokens[AND_IF]);
- if (!ft_strcmp(str, "||"))
- return (g_tokens[OR_IF]);
- if (!ft_strcmp(str, "<"))
- return (g_tokens[LESS]);
- if (!ft_strcmp(str, ">"))
- return (g_tokens[GREAT]);
- if (!ft_strcmp(str, "<<"))
- return (g_tokens[DLESS]);
- if (!ft_strcmp(str, ">>"))
- return (g_tokens[DGREAT]);
- if (!ft_strcmp(str, "|"))
- return (g_tokens[PIPE]);
- if (!ft_strcmp(str, "("))
- return (g_tokens[LPARA]);
- if (!ft_strcmp(str, ")"))
- return (g_tokens[RPARA]);
- if (is_assignment_word(str))
- return (g_tokens[ASSIGNMENT_WORD]);
- if (only_contains_digits(str) && (next == '<' || next == '>'))
- return (g_tokens[IO_NUMBER]);
- return (g_tokens[WORD]);
-}
-
-int handle_quote(t_vec *current_token, char *line, char quote_char, size_t *i)
-{
- if (ft_vec_append(current_token, line + (*i)++) != success)
- return (1);
- while (line[*i] != quote_char)
- {
- if (!line[*i])
- return (1);
- else
- if (ft_vec_append(current_token, line + (*i)++) != success)
- return (1);
- }
- ft_vec_append(current_token, line + (*i)++);
- return (0);
-}
-
-// This function turns the input char string into a string of tokens
-// It possibly should use ft_strdup(ft_vec_access(¤t_token, 0))
-// as that only relies on the consecutivness of memory of t_vec
-int finish_token(t_vec *tokens, t_vec *current_token, char next)
-{
- t_token token;
-
- if (ft_vec_append(current_token, "") != success)
- return (1);
- token.type = (char *)get_token_type(current_token->vec, next);
- if (!token.type)
- return (1);
- token.str = current_token->vec;
- if (ft_vec_append(tokens, &token) != success)
- return (1);
- return (ft_vec_init(current_token, sizeof(char)) != success);
-}
-
-int is_redirection_operator(const t_token *token)
+static int is_redirection_operator(const t_token *token)
{
return (token->type == g_tokens[LESS]
|| token->type == g_tokens[DLESS]
|| token->type == g_tokens[DGREAT]);
}
-int assignment_may_follow(const char *type)
+static int assignment_may_follow(const char *type)
{
return (type == g_tokens[ASSIGNMENT_WORD]
|| type == g_tokens[AND_IF]
|| type == g_tokens[LPARA]);
}
-void filter_assignment_word(t_vec *tokens)
+static void filter_assignment_word(t_vec *tokens)
{
size_t i;
t_token *token;
}
}
-int categorization_step(char *line, size_t *i,
- t_vec *current_token, t_vec *tokens)
-{
- int res;
-
- if (is_operator_start(current_token->vec, current_token->size)
- && can_expand_operator(current_token, line[*i]))
- res = (ft_vec_append(current_token, line + (*i)++) != success);
- else if (is_operator(current_token))
- res = finish_token(tokens, current_token, '\0');
- else if (line[*i] == '\'')
- res = handle_quote(current_token, line, '\'', i);
- else if (line[*i] == '"' )
- res = handle_quote(current_token, line, '"', i);
- else if (is_operator_start(line + *i, 1) || ft_isspace(line[*i]))
- {
- if (current_token->size > 0)
- res = finish_token(tokens, current_token, line[*i]);
- if (!ft_isspace(line[*i]))
- res = res || ft_vec_append(current_token, line + *i)
- != success;
- ++*i;
- }
- else if (current_token->size > 0)
- res = ft_vec_append(current_token, line + (*i)++) != success;
- else
- res = ft_vec_append(current_token, line + (*i)++) != success;
- return (res);
-}
-
int tokenize(char *line, t_vec *tokens)
{
t_vec current_token;
/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/31 14:35:06 by lnikolov #+# #+# */
-/* Updated: 2024/08/31 14:44:27 by lnikolov ### ########.fr */
+/* Updated: 2024/08/31 14:52:36 by lnikolov ### ########.fr */
/* */
/* ************************************************************************** */
return (ft_strndup(line, i));
}
-static int add_var_line(t_vec *vec, const char *line)
+int add_var_line(t_vec *vec, const char *line)
{
char *tmp;
/* +:+ +:+ +:+ */
/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
-/* Created: 2024/08/08 10:50:26 by ljiriste #+# #+# */
-/* Updated: 2024/08/31 13:24:09 by ljiriste ### ########.fr */
+/* Created: 2024/08/31 16:00:03 by lnikolov #+# #+# */
+/* Updated: 2024/08/31 16:28:09 by lnikolov ### ########.fr */
/* */
/* ************************************************************************** */
#include <sys/types.h>
#include <dirent.h>
-int add_entry(t_vec *expanded, t_wildcard_info *info)
-{
- char *new_expanded;
-
- new_expanded = ft_strjoin(info->path, info->entry);
- if (!new_expanded)
- return (1);
- if (ft_vec_append(expanded, &new_expanded) != success)
- {
- free(new_expanded);
- return (1);
- }
- return (0);
-}
-
-int branch_at_star(t_vec *expanded, t_wildcard_info *info)
-{
- const size_t start_size = expanded->size;
- t_wildcard_info info_dup;
-
- if (g_last_signal != 0)
- return (2);
- info_dup = *info;
- if (!(*(info->current_expand_char + 1) == '/' && info->current_entry_char
- == info->entry))
- {
- ++info->current_expand_char;
- if (add_conformant(expanded, info, '\0'))
- return (1);
- }
- if (start_size != expanded->size || *info->current_entry_char == '\0')
- return (0);
- ++info_dup.current_entry_char;
- return (add_conformant(expanded, &info_dup, '\0'));
-}
-
-int expand_further(t_vec *expanded, t_wildcard_info info)
-{
- size_t path_len;
- char *new_path;
- int res;
-
- path_len = ft_strlen(info.path) + ft_strlen(info.entry);
- new_path = malloc(path_len + 2);
- if (!new_path)
- return (1);
- ft_strlcpy(new_path, info.path, path_len + 2);
- ft_strlcat(new_path, info.entry, path_len + 2);
- new_path[path_len] = '/';
- new_path[path_len + 1] = '\0';
- info.path = new_path;
- info.to_expand = info.current_expand_char;
- res = expand_dir(expanded, &info);
- free(new_path);
- return (res);
-}
-
-int add_conformant_part2(t_vec *expanded, t_wildcard_info *info, char quote)
-{
- if (*info->current_expand_char == '\'' || *info->current_expand_char == '"')
- {
- if (!quote)
- quote = *info->current_expand_char;
- else if (quote == *info->current_expand_char)
- quote = '\0';
- else
- --info->current_expand_char;
- ++info->current_expand_char;
- return (add_conformant(expanded, info, quote));
- }
- if ((*info->current_expand_char == '?' && *info->current_entry_char != '\0'
- && (*info->current_entry_char != '.'
- || info->current_entry_char != info->entry) && !quote)
- || (*info->current_expand_char == *info->current_entry_char
- && (*info->current_expand_char != '*' || quote)))
- {
- ++info->current_expand_char;
- ++info->current_entry_char;
- return (add_conformant(expanded, info, quote));
- }
- if (*info->current_expand_char == '*' && (*info->current_entry_char != '.'
- || info->current_entry_char != info->entry) && !quote)
- return (branch_at_star(expanded, info));
- return (0);
-}
-
-int add_conformant(t_vec *expanded, t_wildcard_info *info, char quote)
-{
- if (g_last_signal != 0)
- return (2);
- if (*info->current_expand_char == '\0' && *info->current_entry_char == '\0')
- return (add_entry(expanded, info));
- if (*info->current_expand_char == '/' && *info->current_entry_char == '\0')
- {
- ++info->current_expand_char;
- return (expand_further(expanded, *info));
- }
- if (*info->current_expand_char == '/' && info->current_entry_char
- == info->entry)
- {
- ++info->current_expand_char;
- return (add_conformant(expanded, info, quote));
- }
- return (add_conformant_part2(expanded, info, quote));
-}
-
int expand_dir(t_vec *expanded, t_wildcard_info *info)
{
DIR *dir;
return (0);
}
-// Adding one byte more to the str in case '\n' needs o be appended
-int replace_str_by_joint_split(char **str, char **expanded_split)
-{
- char *tmp;
- size_t len;
- size_t i;
-
- tmp = *str;
- len = 0;
- i = 0;
- while (expanded_split[i])
- len += ft_strlen(expanded_split[i++]) + 1;
- *str = malloc(len + 1 + 1);
- if (!str)
- {
- *str = tmp;
- return (1);
- }
- str[0][0] = '\0';
- i = 0;
- while (expanded_split[i])
- {
- ft_strlcat(*str, expanded_split[i++], len + 1 + 1);
- ft_strlcat(*str, " ", len + 1 + 1);
- }
- free(tmp);
- return (0);
-}
-
-int replace_str_by_joint_quoted_split(char **str, char **expanded_split)
-{
- char *tmp;
- size_t len;
- size_t i;
-
- len = 0;
- i = 0;
- while (expanded_split[i])
- len += ft_strlen(expanded_split[i++]) + 2 + 1;
- tmp = malloc(len + 1 + 1);
- if (!tmp)
- return (1);
- free(*str);
- *str = tmp;
- str[0][0] = '\0';
- i = 0;
- while (expanded_split[i])
- {
- ft_strlcat(*str, "'", len + 1 + 1);
- ft_strlcat(*str, expanded_split[i++], len + 1 + 1);
- ft_strlcat(*str, "'", len + 1 + 1);
- ft_strlcat(*str, " ", len + 1 + 1);
- }
- return (0);
-}
-
-int expand_vars(char **str, const t_execution_env *env)
-{
- t_vec expanded;
-
- if (ft_vec_init(&expanded, sizeof(char)) != success)
- return (1);
- if (add_word(&expanded, *str, env, 1))
- {
- ft_vec_free(&expanded, NULL);
- return (1);
- }
- *(char *)ft_vec_access(&expanded, expanded.size - 1) = '\0';
- free(*str);
- *str = expanded.vec;
- return (0);
-}
-
-char *get_start_path(const char *str, const t_execution_env *env)
-{
- char *unquoted_str;
- char *res;
-
- unquoted_str = ft_strdup(str);
- unquote_field(unquoted_str);
- if (unquoted_str[0] == '/')
- res = ft_strdup("/");
- else if (unquoted_str[0] == '~' && (ft_isalpha(unquoted_str[1])
- || unquoted_str[1] == '/' || unquoted_str[1] == '~'
- || unquoted_str[1] == '+' || unquoted_str[1] == '-'))
- {
- if (unquoted_str[1] == '/' || unquoted_str[1] == '\0')
- res = ft_strjoin(get_env_var_value(env, "HOME"), "/");
- else
- {
- free(unquoted_str);
- return (NULL);
- }
- }
- else
- res = ft_strdup("");
- free(unquoted_str);
- return (res);
-}
-
-int expand_word_inner(char **str, const t_execution_env *env)
+static int expand_word_inner(char **str, const t_execution_env *env)
{
const char *nullptr = NULL;
t_vec matched;
return (res);
}
-int expand_word(char **str, const t_execution_env *env)
+static int expand_word(char **str, const t_execution_env *env)
{
int res;
char last_char;
return (res);
}
-int should_be_expanded(const char *word)
+static int expand_vars(char **str, const t_execution_env *env)
{
- size_t i;
- char quote_char;
+ t_vec expanded;
- quote_char = '\0';
- i = 0;
- while (word[i])
+ if (ft_vec_init(&expanded, sizeof(char)) != success)
+ return (1);
+ if (add_word(&expanded, *str, env, 1))
{
- if ((word[i] == '*' || (word[i] == '?' && !(i && word[i - 1] == '$')))
- && quote_char == '\0')
- return (1);
- if (word[i] == '"' || word[i] == '\'')
- {
- if (quote_char == '\0')
- quote_char = word[i];
- else if (quote_char == word[i])
- quote_char = '\0';
- }
- ++i;
+ ft_vec_free(&expanded, NULL);
+ return (1);
}
+ *(char *)ft_vec_access(&expanded, expanded.size - 1) = '\0';
+ free(*str);
+ *str = expanded.vec;
return (0);
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* wildcards_helpers.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/08/31 15:57:29 by lnikolov #+# #+# */
+/* Updated: 2024/08/31 16:28:30 by lnikolov ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "minishell_structs.h"
+#include "minishell.h"
+#include "libft.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+// Adding one byte more to the str in case '\n' needs o be appended
+int replace_str_by_joint_split(char **str, char **expanded_split)
+{
+ char *tmp;
+ size_t len;
+ size_t i;
+
+ tmp = *str;
+ len = 0;
+ i = 0;
+ while (expanded_split[i])
+ len += ft_strlen(expanded_split[i++]) + 1;
+ *str = malloc(len + 1 + 1);
+ if (!str)
+ {
+ *str = tmp;
+ return (1);
+ }
+ str[0][0] = '\0';
+ i = 0;
+ while (expanded_split[i])
+ {
+ ft_strlcat(*str, expanded_split[i++], len + 1 + 1);
+ ft_strlcat(*str, " ", len + 1 + 1);
+ }
+ free(tmp);
+ return (0);
+}
+
+int replace_str_by_joint_quoted_split(char **str, char **expanded_split)
+{
+ char *tmp;
+ size_t len;
+ size_t i;
+
+ len = 0;
+ i = 0;
+ while (expanded_split[i])
+ len += ft_strlen(expanded_split[i++]) + 2 + 1;
+ tmp = malloc(len + 1 + 1);
+ if (!tmp)
+ return (1);
+ free(*str);
+ *str = tmp;
+ str[0][0] = '\0';
+ i = 0;
+ while (expanded_split[i])
+ {
+ ft_strlcat(*str, "'", len + 1 + 1);
+ ft_strlcat(*str, expanded_split[i++], len + 1 + 1);
+ ft_strlcat(*str, "'", len + 1 + 1);
+ ft_strlcat(*str, " ", len + 1 + 1);
+ }
+ return (0);
+}
+
+char *get_start_path(const char *str, const t_execution_env *env)
+{
+ char *unquoted_str;
+ char *res;
+
+ unquoted_str = ft_strdup(str);
+ unquote_field(unquoted_str);
+ if (unquoted_str[0] == '/')
+ res = ft_strdup("/");
+ else if (unquoted_str[0] == '~' && (ft_isalpha(unquoted_str[1])
+ || unquoted_str[1] == '/' || unquoted_str[1] == '~'
+ || unquoted_str[1] == '+' || unquoted_str[1] == '-'))
+ {
+ if (unquoted_str[1] == '/' || unquoted_str[1] == '\0')
+ res = ft_strjoin(get_env_var_value(env, "HOME"), "/");
+ else
+ {
+ free(unquoted_str);
+ return (NULL);
+ }
+ }
+ else
+ res = ft_strdup("");
+ free(unquoted_str);
+ return (res);
+}
+
+int should_be_expanded(const char *word)
+{
+ size_t i;
+ char quote_char;
+
+ quote_char = '\0';
+ i = 0;
+ while (word[i])
+ {
+ if ((word[i] == '*' || (word[i] == '?' && !(i && word[i - 1] == '$')))
+ && quote_char == '\0')
+ return (1);
+ if (word[i] == '"' || word[i] == '\'')
+ {
+ if (quote_char == '\0')
+ quote_char = word[i];
+ else if (quote_char == word[i])
+ quote_char = '\0';
+ }
+ ++i;
+ }
+ return (0);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* wildcards_inner.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: lnikolov <lnikolov@student.42prague.com +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/08/08 10:50:26 by ljiriste #+# #+# */
+/* Updated: 2024/08/31 16:28:57 by lnikolov ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "minishell_structs.h"
+#include "minishell.h"
+#include "libft.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+static int add_entry(t_vec *expanded, t_wildcard_info *info)
+{
+ char *new_expanded;
+
+ new_expanded = ft_strjoin(info->path, info->entry);
+ if (!new_expanded)
+ return (1);
+ if (ft_vec_append(expanded, &new_expanded) != success)
+ {
+ free(new_expanded);
+ return (1);
+ }
+ return (0);
+}
+
+static int branch_at_star(t_vec *expanded, t_wildcard_info *info)
+{
+ const size_t start_size = expanded->size;
+ t_wildcard_info info_dup;
+
+ if (g_last_signal != 0)
+ return (2);
+ info_dup = *info;
+ if (!(*(info->current_expand_char + 1) == '/' && info->current_entry_char
+ == info->entry))
+ {
+ ++info->current_expand_char;
+ if (add_conformant(expanded, info, '\0'))
+ return (1);
+ }
+ if (start_size != expanded->size || *info->current_entry_char == '\0')
+ return (0);
+ ++info_dup.current_entry_char;
+ return (add_conformant(expanded, &info_dup, '\0'));
+}
+
+static int expand_further(t_vec *expanded, t_wildcard_info info)
+{
+ size_t path_len;
+ char *new_path;
+ int res;
+
+ path_len = ft_strlen(info.path) + ft_strlen(info.entry);
+ new_path = malloc(path_len + 2);
+ if (!new_path)
+ return (1);
+ ft_strlcpy(new_path, info.path, path_len + 2);
+ ft_strlcat(new_path, info.entry, path_len + 2);
+ new_path[path_len] = '/';
+ new_path[path_len + 1] = '\0';
+ info.path = new_path;
+ info.to_expand = info.current_expand_char;
+ res = expand_dir(expanded, &info);
+ free(new_path);
+ return (res);
+}
+
+static int add_conformant_part2(t_vec *expanded,
+ t_wildcard_info *info, char quote)
+{
+ if (*info->current_expand_char == '\'' || *info->current_expand_char == '"')
+ {
+ if (!quote)
+ quote = *info->current_expand_char;
+ else if (quote == *info->current_expand_char)
+ quote = '\0';
+ else
+ --info->current_expand_char;
+ ++info->current_expand_char;
+ return (add_conformant(expanded, info, quote));
+ }
+ if ((*info->current_expand_char == '?' && *info->current_entry_char != '\0'
+ && (*info->current_entry_char != '.'
+ || info->current_entry_char != info->entry) && !quote)
+ || (*info->current_expand_char == *info->current_entry_char
+ && (*info->current_expand_char != '*' || quote)))
+ {
+ ++info->current_expand_char;
+ ++info->current_entry_char;
+ return (add_conformant(expanded, info, quote));
+ }
+ if (*info->current_expand_char == '*' && (*info->current_entry_char != '.'
+ || info->current_entry_char != info->entry) && !quote)
+ return (branch_at_star(expanded, info));
+ return (0);
+}
+
+int add_conformant(t_vec *expanded, t_wildcard_info *info, char quote)
+{
+ if (g_last_signal != 0)
+ return (2);
+ if (*info->current_expand_char == '\0' && *info->current_entry_char == '\0')
+ return (add_entry(expanded, info));
+ if (*info->current_expand_char == '/' && *info->current_entry_char == '\0')
+ {
+ ++info->current_expand_char;
+ return (expand_further(expanded, *info));
+ }
+ if (*info->current_expand_char == '/' && info->current_entry_char
+ == info->entry)
+ {
+ ++info->current_expand_char;
+ return (add_conformant(expanded, info, quote));
+ }
+ return (add_conformant_part2(expanded, info, quote));
+}