From 82ddadbea308ff712a510b836b51adf299c08d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Thu, 21 May 2020 18:12:21 +0200 Subject: [PATCH] vars are correctly parsed in deouble quotes --- Makefile | 4 ++- include/parser.h | 14 ++++++-- src/parser/double_quotes.c | 28 +++++++++++++++ src/parser/parser.c | 18 ++++++---- src/parser/parser_utilities.c | 47 +++++++++++++++++++++++++ src/parser/parser_vars_utilities.c | 56 ++++++++++++++++++++++++++++++ src/parser/quotes.c | 14 ++------ src/prompt.c | 10 +++--- 8 files changed, 164 insertions(+), 27 deletions(-) create mode 100644 src/parser/double_quotes.c create mode 100644 src/parser/parser_vars_utilities.c diff --git a/Makefile b/Makefile index 1fd2b91..8109826 100644 --- a/Makefile +++ b/Makefile @@ -37,10 +37,12 @@ SRC = src/shell.c \ src/utility/envpath.c \ src/utility/fusion.c \ src/utility/split_commands.c \ - src/utility/get_return.c \ + src/utility/get_return.c \ src/parser/parser.c \ src/parser/quotes.c \ + src/parser/double_quotes.c \ src/parser/parser_utilities.c \ + src/parser/parser_vars_utilities.c \ src/key_bindings/basic_typing_functions.c \ src/key_bindings/default_bindings.c \ src/key_bindings/control_commands.c \ diff --git a/include/parser.h b/include/parser.h index 638a8ea..b72bd92 100644 --- a/include/parser.h +++ b/include/parser.h @@ -13,13 +13,21 @@ typedef struct parser_map { char key; - int (*parser)(char *, char **); + int (*parser)(char *, char **, env_t *); } parser_map; -char **parse_input(char *cmd); -int parse_quotes(char *ptr, char **data); +char **parse_input(char *cmd, env_t *env); + +int parse_quotes(char *ptr, char **data, env_t *env); +int parse_double_quotes(char *ptr, char **data, env_t *env); char *strcat_realloc(char *dest, char *src); char *add_to_buffer(char *buffer, char *ptr, int nb, bool inhibitors); +char *get_var_value(char *var, env_t *env); + +void insert_substring(char *dest, char *src, int position); + +char *process_vars(char *cmd, env_t *env); +void rm_n_char(char *ptr, int n); void remove_inhibitors_symbols_n_limit(char *str, int nb); \ No newline at end of file diff --git a/src/parser/double_quotes.c b/src/parser/double_quotes.c new file mode 100644 index 0000000..cd24e07 --- /dev/null +++ b/src/parser/double_quotes.c @@ -0,0 +1,28 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#include "parser.h" +#include + +int parse_double_quotes(char *ptr, char **data, env_t *env) +{ + int length = 0; + char *ptr_end = strchr(&ptr[1], '"'); + char *cmd; + + if (!ptr_end) { + dprintf(2, "Unmatched '\"'.\n"); + return (-1); + } + length = (ptr_end - ptr) / sizeof(char); + cmd = strndup(&ptr[1], length); + if (!cmd) + return (-1); + cmd[length - 1] = '\0'; + *data = process_vars(cmd, env); + return (length); +} \ No newline at end of file diff --git a/src/parser/parser.c b/src/parser/parser.c index 591641f..5b43c5d 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -18,6 +18,7 @@ const parser_map parsers[] = { {'\'', &parse_quotes}, + {'"', &parse_double_quotes}, {'\0', NULL} }; @@ -37,25 +38,27 @@ bool is_character_valid(char c) return (false); } -int call_parsers(char *cmd, int index, char **data) +int call_parsers(char *cmd, int index, char **data, env_t *env) { int new_index = 0; for (int i = 0; parsers[i].key; i++) { if (cmd[index] != parsers[i].key) continue; - new_index = parsers[i].parser(&cmd[index], data); + new_index = parsers[i].parser(&cmd[index], data, env); + if (!(*data)) + return (-1); return (new_index); } return (0); } -int manage_specials_parsers(char *cmd, char **buffer, int *inc, char **ptr) +int manage_specials_parsers(char *cmd, char **buffer, int *inc, char **ptr, env_t *env) { int new_index = 0; char *data = NULL; - new_index = call_parsers(cmd, 0, &data); + new_index = call_parsers(cmd, 0, &data, env); if (new_index == -1) return (-1); if (new_index > 0) { @@ -71,7 +74,7 @@ int manage_specials_parsers(char *cmd, char **buffer, int *inc, char **ptr) return (0); } -char **parse_input(char *cmd) +char **parse_input(char *cmd, env_t *env) { char **ret = malloc(sizeof(char *) * (strlen(cmd) + 1)); char *ptr = cmd; @@ -83,13 +86,13 @@ char **parse_input(char *cmd) return (NULL); for (int i = 0, inc = 1; i <= (int)strlen(cmd); i++, inc++) { if (is_character_valid(cmd[i])) { - new_index = manage_specials_parsers(&cmd[i], &buffer, &inc, &ptr); + new_index = manage_specials_parsers(&cmd[i], &buffer, &inc, &ptr, env); if (new_index == -1) return (NULL); i += new_index; continue; } - if (inc == 1) { + if (inc == 1 && !new_index) { ptr = cmd + i + 1; inc = 0; continue; @@ -101,6 +104,7 @@ char **parse_input(char *cmd) buffer = NULL; ptr = cmd + i + 1; inc = 0; + new_index = 0; } ret[ret_inc] = NULL; return (ret); diff --git a/src/parser/parser_utilities.c b/src/parser/parser_utilities.c index 04bb2a8..ca08832 100644 --- a/src/parser/parser_utilities.c +++ b/src/parser/parser_utilities.c @@ -8,7 +8,22 @@ #include #include "parser.h" +char *get_var_value(char *var, env_t *env) +{ + char *value; + if (!var) + return (NULL); + value = my_getenv(env->env, var); + if (value) + return (value); + value = my_getenv(env->vars, var); + if (value) + return (value); + printf("%s: Undefined variable.\n", var); + env->vars = my_setenv(env->vars, "?", "1"); + return (NULL); +} char *strcat_realloc(char *dest, char *src) { @@ -53,4 +68,36 @@ void remove_inhibitors_symbols_n_limit(char *str, int nb) i++; } } +} + +char *substring(char *string, int position, int length) +{ + char *pointer = malloc(length + 1); + int i; + + if(pointer == NULL) + return (NULL); + for(i = 0; i < length; i++) + *(pointer + i) = *((string + position - 1) + i); + *(pointer + i) = '\0'; + return (pointer); +} + +void insert_substring(char *dest, char *src, int position) +{ + char *f; + char *e; + int length; + + length = strlen(dest); + + f = substring(dest, 1, position - 1); + e = substring(dest, position, length - position + 1); + + strcpy(dest, ""); + strcat(dest, f); + free(f); + strcat(dest, src); + strcat(dest, e); + free(e); } \ No newline at end of file diff --git a/src/parser/parser_vars_utilities.c b/src/parser/parser_vars_utilities.c new file mode 100644 index 0000000..9ec48de --- /dev/null +++ b/src/parser/parser_vars_utilities.c @@ -0,0 +1,56 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#include "parser.h" +#include +#include + +int get_var_name(char *ptr, char **name) +{ + int length = 0; + + for (int i = 1; ptr[i] && ptr[i] != ' ' && ptr[i] != '$'; i++) { + length++; + } + *name = strndup(&ptr[1], length); + return (length + 1); +} + +void rm_n_char(char *ptr, int n) +{ + int i; + + for (i = 0; ptr[i + n]; i++) { + ptr[i] = ptr[i + n]; + } + ptr[i] = '\0'; +} + +char *process_vars(char *cmd, env_t *env) +{ + char *name = NULL; + char *value; + int new_index; + int length = strlen(cmd); + + for (int i = 0; i < length; i++, length = strlen(cmd)) { + if (cmd[i] != '$') + continue; + new_index = get_var_name(&cmd[i], &name); + value = get_var_value(name, env); + if (!value) + return (NULL); + cmd = realloc(cmd, sizeof(char) * (strlen(value) + length + 2)); + if (!cmd) + return (NULL); + rm_n_char(&cmd[i], strlen(name) + 1); + insert_substring(cmd, value, i + 1); + i += new_index; + free(name); + } + return (cmd); +} \ No newline at end of file diff --git a/src/parser/quotes.c b/src/parser/quotes.c index f9a51ce..ca0f276 100644 --- a/src/parser/quotes.c +++ b/src/parser/quotes.c @@ -5,22 +5,14 @@ ** redirections */ - -#include "shell.h" -#include "redirections.h" -#include -#include -#include +#include "parser.h" #include -#include -#include -#include "utility.h" -#include "builtin.h" -int parse_quotes(char *ptr, char **data) +int parse_quotes(char *ptr, char **data, env_t *env) { int length = 0; char *ptr_end = strchr(&ptr[1], '\''); + (void)env; if (!ptr_end) { dprintf(2, "Unmatched '''.\n"); diff --git a/src/prompt.c b/src/prompt.c index 417373a..7f9eb37 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -34,16 +34,16 @@ const builtin builtins[] = { int prompt_run(char *cmd, redirection *inout[2], env_t *env) { //char **argv = get_argv(cmd); - char **argv = parse_input(cmd); + char **argv = parse_input(cmd, env); + if (!argv) { + //perror(SHELL_NAME); + return (0); + } for (int i = 0; argv[i]; i++) { printf("'%s'\n", argv[i]); } return (0); - if (!argv) { - perror(SHELL_NAME); - return (-1); - } for (int i = 0; argv[i]; i++) printf("argv[%i] : %s\n", i , argv[i]); if (!argv[0])