From: Lilia-42 Date: Sat, 31 Aug 2024 16:19:35 +0000 (+0200) Subject: Refactor some files to comply with the 42 Norm X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=f056791099bd94b51d171f660f2525c303e92fd7;p=42%2Fminishell.git Refactor some files to comply with the 42 Norm tokenization.c and wildcards.c were each split to 3 files to comply with the "max 5 functions per file" rule of the Norm --- diff --git a/Makefile b/Makefile index 92ccf33..3e73d4c 100644 --- a/Makefile +++ b/Makefile @@ -28,10 +28,15 @@ SOURCES := main.c \ 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 \ diff --git a/inc/minishell.h b/inc/minishell.h index 92318d8..7a3369c 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* minishell.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: ljiriste +#+ +:+ +#+ */ +/* By: lnikolov +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); @@ -30,13 +46,19 @@ void handle_input(char **line, t_execution_env *env); 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 diff --git a/inc/minishell_structs.h b/inc/minishell_structs.h index d38c1cc..92aa0f8 100644 --- a/inc/minishell_structs.h +++ b/inc/minishell_structs.h @@ -6,7 +6,7 @@ /* By: lnikolov + +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); +} diff --git a/src/token_finish.c b/src/token_finish.c new file mode 100644 index 0000000..b038691 --- /dev/null +++ b/src/token_finish.c @@ -0,0 +1,67 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_finish.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lnikolov + +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); +} diff --git a/src/tokenization.c b/src/tokenization.c index 505774a..d0ffe6e 100644 --- a/src/tokenization.c +++ b/src/tokenization.c @@ -3,160 +3,18 @@ /* ::: :::::::: */ /* tokenization.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: lnikolov +#+ +:+ +#+ */ +/* By: lnikolov -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] @@ -164,7 +22,7 @@ int is_redirection_operator(const t_token *token) || 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] @@ -172,7 +30,7 @@ int assignment_may_follow(const char *type) || 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; @@ -199,36 +57,6 @@ void filter_assignment_word(t_vec *tokens) } } -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; diff --git a/src/vars.c b/src/vars.c index dc88fb8..fbb06b6 100644 --- a/src/vars.c +++ b/src/vars.c @@ -6,7 +6,7 @@ /* By: lnikolov #include -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; @@ -151,107 +45,7 @@ int expand_dir(t_vec *expanded, t_wildcard_info *info) 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; @@ -277,7 +71,7 @@ int expand_word_inner(char **str, const t_execution_env *env) 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; @@ -294,27 +88,20 @@ int expand_word(char **str, const t_execution_env *env) 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); } diff --git a/src/wildcards_helpers.c b/src/wildcards_helpers.c new file mode 100644 index 0000000..7a71494 --- /dev/null +++ b/src/wildcards_helpers.c @@ -0,0 +1,125 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* wildcards_helpers.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lnikolov +#include +#include + +// 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); +} diff --git a/src/wildcards_inner.c b/src/wildcards_inner.c new file mode 100644 index 0000000..2d5bdf5 --- /dev/null +++ b/src/wildcards_inner.c @@ -0,0 +1,125 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* wildcards_inner.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lnikolov +#include +#include + +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)); +}