diff --git a/Makefile b/Makefile index 0cdfab5..200c9d7 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,8 @@ SRC = src/shell.c \ src/prompt.c \ - src/alias.c \ src/execute.c \ - src/glob.c \ + src/alias.c \ src/redirections/redirection_manager.c \ src/redirections/redirections.c \ src/redirections/redirections_functions.c \ @@ -39,6 +38,11 @@ SRC = src/shell.c \ src/utility/fusion.c \ src/utility/split_commands.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/utility/eof.c \ src/key_bindings/basic_typing_functions.c \ src/key_bindings/default_bindings.c \ @@ -57,7 +61,7 @@ TESTS = tests/tenv.c \ tests/targc.c \ tests/texecute.c \ tests/tcd.c \ - tests/tsource.c \ + tests/tsource.c \ tests/techo.c COVERAGE = -lcriterion --coverage @@ -80,7 +84,7 @@ $(NAME): $(OBJ) $(CC) -o $(NAME) $(OBJ) $(LDFLAGS) tests_run: clean - $(CC) -o $(UT) $(TESTS) $(SRC) $(COVERAGE) $(CFLAGS) $(LDFLAGS) + $(CC) -o $(UT) $(TESTS) $(SRC) $(COVERAGE) -g $(CFLAGS) $(LDFLAGS) $(UT) func: all diff --git a/include/builtin.h b/include/builtin.h index 9f31465..f705f3c 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -30,12 +30,13 @@ int builtin_alias(char **args, env_t *env); int builtin_unalias(char **args, env_t *env); int builtin_bindkey(char **argv, env_t *env); int builtin_echo(char **args, env_t *env); -//utility +//which / where bool find_path_in_builtins(char *cmd); char **get_envpath(env_t *env); char *check_executable(char *cmd, char *folder); char **get_paths_from_envpath(char *cmd, char **envpath); char **get_envpath(env_t *env); +void fill_path_arr(char *cmd, char **envpath, char **res); //history int add_to_history(char *cmd, env_t *env); int show_history(env_t *env); diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 0000000..4c167f6 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#pragma once + +#include "shell.h" +#include +#include +#include + +typedef struct parser_map { + char key; + int (*parser)(char *, char **, env_t *); +} parser_map; + +char **parse_input(char *cmd, env_t *env, wordexp_t *parser); +void free_array(char **array); + +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, env_t *env); +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/include/redirections.h b/include/redirections.h index 1c0c972..14d1d74 100644 --- a/include/redirections.h +++ b/include/redirections.h @@ -19,7 +19,6 @@ typedef enum redirection_type { PTY = 1 << 4 } redirection_type; - typedef struct redirection_map { char *key; int (*get_fd)(redirection *); diff --git a/include/shell.h b/include/shell.h index 23de00a..73bd461 100644 --- a/include/shell.h +++ b/include/shell.h @@ -54,7 +54,7 @@ typedef struct env_s void start_shell(env_t *env); void free_env(env_t *env); -int prompt_run(char *cmd, redirection *inout[2], env_t *env); +int prompt_run(char *cmd, redirection *inout[2], env_t *env, redirection *red); void prompt_prepare(buffer_t *buffer, env_t *env); int eval_raw_cmd(char *cmd, env_t *env); @@ -81,7 +81,6 @@ char **globbing(char **argv); char *get_alias(char *cmd, alias_t *alias); char *add_separator(char *cmd, int *return_values, int index); -char *replace_alias(char *cmd, alias_t *alias); char *get_alias_command(char *cmd, alias_t *alias); diff --git a/include/utility.h b/include/utility.h index 4541e4d..28e1a1f 100644 --- a/include/utility.h +++ b/include/utility.h @@ -17,16 +17,17 @@ bool is_alpha(char c); bool is_num(char c); bool envvar_is_valid(const char *str); int count_str(char *str, char *delim); -char **split_str(char *str, char delim); +char **split_str(char *str, char **delims); char *same_var(char *str, const char *to_find); void destroy_str_arr(char **arr); char *fusion(char *command, char **args); -char **split_commands(char *cmd); int *get_return_separator(char *cmd); int split_is_invalid(char **cmds, int *return_values, int i); int count_char(const char *str, char c); int ncount_char(const char *str, int end, char c); int get_max_eof(char *ignoreeof); int skip_eof(buffer_t *buffer, env_t *env); +int count_trailing_spaces(char *cmd); +char **remove_leading_entries(char **cmds); -#define MAX(x, y) ((x) < (y) ? (y) : (x)) \ No newline at end of file +#define MAX(x, y) ((x) < (y) ? (y) : (x)) diff --git a/src/alias.c b/src/alias.c index 8cb30fc..d3139cb 100644 --- a/src/alias.c +++ b/src/alias.c @@ -12,77 +12,16 @@ #include #include -char *get_alias(char *cmd, alias_t *alias) -{ - char **array = split_commands(cmd); - int *return_values = get_return_separator(cmd); - char *final_command = NULL; - - if (!array) - return (cmd); - for (int i = 0; array[i]; i++) { - if (strlen(array[i]) && (strncmp("alias ", array[i], 6) - && strncmp("unalias ", array[i], 8))) - array[i] = replace_alias(array[i], alias); - array[i] = add_separator(array[i], return_values, i); - if (!array[i]) - return (NULL); - } - final_command = fusion(array[0], array); - return (final_command); -} - -char *replace_alias(char *cmd, alias_t *alias) -{ - char **arg_array = split_str(cmd, ' '); - char *final_str = NULL; - - if (!arg_array) - return (NULL); - for (int i = 0; arg_array[i]; i++) { - arg_array[i] = get_alias_command(arg_array[i], alias); - if (!arg_array[i]) - return (NULL); - } - final_str = fusion(arg_array[0], arg_array); - return (final_str); -} - char *get_alias_command(char *cmd, alias_t *alias) { alias_t *tmp = NULL; tmp = alias; for (; tmp; tmp = tmp->next) { - if (!strcmp(cmd, alias->alias)) { - cmd = strdup(alias->command); + if (!strcmp(cmd, tmp->alias)) { + cmd = strdup(tmp->command); tmp = alias; } } return (cmd); -} - -char *add_separator(char *cmd, int *return_values, int index) -{ - int pos = 0; - char *new_cmd = NULL; - - if (!cmd) - return (NULL); - new_cmd = calloc(strlen(cmd) + 3, sizeof(char)); - if (!new_cmd) - return (NULL); - for (int i = 0; cmd[i]; i++) - new_cmd[i] = cmd[pos++]; - if (return_values[index + 1] != -2) { - new_cmd[pos] = ';'; - if (return_values[index + 1] == 1) { - new_cmd[pos++] = '|'; - new_cmd[pos++] = '|'; - } else if (return_values[index + 1] == 0) { - new_cmd[pos++] = '&'; - new_cmd[pos++] = '&'; - } - } - return (new_cmd); } \ No newline at end of file diff --git a/src/builtin/builtin_alias.c b/src/builtin/builtin_alias.c index c548416..1225ede 100644 --- a/src/builtin/builtin_alias.c +++ b/src/builtin/builtin_alias.c @@ -33,8 +33,10 @@ int add_alias(alias_t **list, char *alias, char **command) elem = malloc(sizeof(alias_t)); if (!elem) return (-1); - *elem = (alias_t){alias, concatenate(command), NULL}; - if (!elem->command) + elem->alias = strdup(alias); + elem->command = concatenate(command); + elem->next = NULL; + if (!elem->command || !elem->alias) return (-1); if (*list == NULL) { *list = elem; @@ -75,7 +77,7 @@ char *concatenate(char **command) int pos = 0; if (!command[1]) - return (command[0]); + return (strdup(command[0])); for (int i = 0; command[i]; i++) total_len += strlen(command[i]) + 1; concatened = calloc(total_len + 1, sizeof(char)); @@ -93,8 +95,6 @@ char *concatenate(char **command) void print_aliases(alias_t *list) { - for (alias_t *tmp = list; tmp; tmp = tmp->next) { + for (alias_t *tmp = list; tmp; tmp = tmp->next) printf("%s\t%s\n", tmp->alias, tmp->command); - fflush(stdout); - } } \ No newline at end of file diff --git a/src/builtin/builtin_env.c b/src/builtin/builtin_env.c index 57f073e..c8932b8 100644 --- a/src/builtin/builtin_env.c +++ b/src/builtin/builtin_env.c @@ -18,7 +18,6 @@ int builtin_env(char **argv, env_t *env) write(1, "\n", 1); } env->vars = my_setenv(env->vars, "?", "0"); - free(argv); return (0); } @@ -39,7 +38,6 @@ int builtin_setenv(char **argv, env_t *env) } env->env = my_setenv(env->env, argv[1], argv[2]); env->vars = my_setenv(env->vars, "?", "0"); - free(argv); return (0); } @@ -48,13 +46,11 @@ int builtin_unsetenv(char **argv, env_t *env) if (!argv[1]) { write(2, "unsetenv: Too few arguments.\n", 29); env->vars = my_setenv(env->vars, "?", "1"); - free(argv); return (0); } for (int i = 1; argv[i]; i++) if (!strchr(argv[i], '=')) env->env = my_unsetenv(env->env, argv[i]); env->vars = my_setenv(env->vars, "?", "0"); - free(argv); return (0); } \ No newline at end of file diff --git a/src/builtin/builtin_history.c b/src/builtin/builtin_history.c index 77804b0..eba538d 100644 --- a/src/builtin/builtin_history.c +++ b/src/builtin/builtin_history.c @@ -37,8 +37,10 @@ int add_to_history(char *cmd, env_t *env) char *command = cmd; for (; *command && (*command == ' ' || *command == '\t'); command++); - if (!strlen(command)) + if (!strlen(command)) { + free(log); return (0); + } if (!log) return (-1); for (tmp = env->history; tmp && tmp->next; tmp = tmp->next); diff --git a/src/builtin/builtin_manager.c b/src/builtin/builtin_manager.c index 2f062e8..801284d 100644 --- a/src/builtin/builtin_manager.c +++ b/src/builtin/builtin_manager.c @@ -46,7 +46,6 @@ int builtin_cd(char **argv, env_t *env) if (get_argc(argv) > 2) { write(2, "cd: Too many arguments.\n", 25); - free(argv); env->vars = my_setenv(env->vars, "?", "1"); return (0); } @@ -61,7 +60,6 @@ int builtin_cd(char **argv, env_t *env) } else env->env = my_setenv(env->env, "OLDPWD", old); free(old); - free(argv); return (0); } @@ -69,6 +67,5 @@ int builtin_exit(char **argv, env_t *env) { if (argv[1]) env->vars = my_setenv(env->vars, "?", "1"); - free(argv); return (-1); } diff --git a/src/builtin/builtin_source.c b/src/builtin/builtin_source.c index a823c2b..e4653f0 100644 --- a/src/builtin/builtin_source.c +++ b/src/builtin/builtin_source.c @@ -25,7 +25,7 @@ char **get_arr_from_fd(int fd, char *filepath, char *str) str = malloc(st_buff.st_size + 1); if (str) { read(fd, str, st_buff.st_size); - arr = split_str(str, '\n'); + arr = split_str(str, (char *[]){"\n", NULL}); } return (arr); } diff --git a/src/builtin/builtin_where.c b/src/builtin/builtin_where.c index 801f7d3..512b564 100644 --- a/src/builtin/builtin_where.c +++ b/src/builtin/builtin_where.c @@ -15,9 +15,18 @@ #include "utility.h" #include "shell.h" +void print_alias_where(char *cmd, char *aliased) +{ + if (aliased[0] == '(') { + aliased = &aliased[1]; + aliased[strlen(aliased) - 1] = 0; + } + printf("%s is aliased to %s\n", cmd, aliased); +} + char *check_executable(char *cmd, char *folder) { - struct stat st_buff; + struct stat st_buff = {}; char *path = catpath(folder, cmd); char *res = path; @@ -58,23 +67,14 @@ void fill_path_arr(char *cmd, char **envpath, char **res) res[counter] = NULL; } -char **get_paths_from_envpath(char *cmd, char **envpath) -{ - int len = 0; - char **res = NULL; - - for (; envpath[len]; len++); - res = malloc(sizeof(char *) * (len + 2)); - if (!res) - return (NULL); - fill_path_arr(cmd, envpath, res); - return (res); -} - -void print_path_no_stop(char *cmd, char **envpath) +void print_path_no_stop(char *cmd, char **envpath, env_t *env) { + char *dup_cmd = strdup(cmd); char **paths = NULL; - //check_alias_no_stop + char *aliased = get_alias_command(cmd, env->alias); + + if (strcmp(aliased, dup_cmd)) + print_alias_where(dup_cmd, aliased); find_path_in_builtins(cmd); if (!envpath) return; @@ -101,7 +101,7 @@ int builtin_where(char **argv, env_t *env) if (strchr(argv[i], '/')) printf("where: / in command makes no sense\n"); else - print_path_no_stop(argv[i], envpath); + print_path_no_stop(argv[i], envpath, env); } free(envpath); return (0); diff --git a/src/builtin/builtin_which.c b/src/builtin/builtin_which.c index 50e88cd..b297532 100644 --- a/src/builtin/builtin_which.c +++ b/src/builtin/builtin_which.c @@ -12,6 +12,28 @@ #include "utility.h" #include "builtin.h" +char **get_paths_from_envpath(char *cmd, char **envpath) +{ + int len = 0; + char **res = NULL; + + for (; envpath[len]; len++); + res = malloc(sizeof(char *) * (len + 2)); + if (!res) + return (NULL); + fill_path_arr(cmd, envpath, res); + return (res); +} + +void print_alias_which(char *cmd, char *aliased) +{ + if (aliased[0] == '(') { + aliased = &aliased[1]; + aliased[strlen(aliased) - 1] = 0; + } + printf("%s:\taliased to %s\n", cmd, aliased); +} + bool find_path_in_builtins(char *cmd) { extern const builtin builtins[]; @@ -24,11 +46,17 @@ bool find_path_in_builtins(char *cmd) return (false); } -void print_path(char *cmd, char **envpath) +void print_path(char *cmd, char **envpath, env_t *env) { char **res = NULL; + char *dup_cmd = strdup(cmd); int len = 0; - //check_alias + char *aliased = get_alias_command(cmd, env->alias); + + if (strcmp(aliased, dup_cmd)) { + print_alias_which(dup_cmd, aliased); + return; + } if (find_path_in_builtins(cmd)) return; res = get_paths_from_envpath(cmd, envpath); @@ -52,7 +80,7 @@ int builtin_which(char **argv, env_t *env) } envpath = get_envpath(env); for (int i = 1; argv[i]; i++) - print_path(argv[i], envpath); + print_path(argv[i], envpath, env); free(envpath); return (0); } \ No newline at end of file diff --git a/src/glob.c b/src/glob.c deleted file mode 100644 index 6113b24..0000000 --- a/src/glob.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -** EPITECH PROJECT, 2020 -** ash -** File description: -** glob -*/ - -#include -#include -#include -#include -#include "shell.h" - -char **glob_error(char **argv, int err) -{ - if (err == GLOB_ABORTED) - fprintf(stderr, "%s: %s\n", argv[0], "Aborted."); - if (err == GLOB_NOMATCH) - fprintf(stderr, "%s: %s\n", argv[0], "No match."); - if (err == GLOB_NOSPACE) - fprintf(stderr, "%s: %s\n", argv[0], "No space."); - free(argv); - return (NULL); -} - -char **globbing(char **argv) -{ - static glob_t results; - int flags = GLOB_DOOFFS | GLOB_NOMAGIC | GLOB_TILDE; - int ret = 0; - - for (int i = 0; argv[i] && ret == 0; i++) { - flags |= (i > 0 ? GLOB_APPEND : 0); - ret = glob(argv[i], flags, NULL, &results); - } - if (ret != 0) { - globfree(&results); - return (glob_error(argv, ret)); - } - free(argv); - return (&results.gl_pathv[0]); -} \ 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 new file mode 100644 index 0000000..75f6d1e --- /dev/null +++ b/src/parser/parser.c @@ -0,0 +1,75 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#define _XOPEN_SOURCE + +#include "parser.h" +#include "shell.h" +#include "redirections.h" +#include "utility.h" +#include "builtin.h" +#include +#include +#include +#include + +char *strdup(const char *); + +int count_trailing_spaces(char *cmd) +{ + int i = 0; + + for (i = 0; cmd[i]; i++) + if (cmd[i] != ' ' && cmd[i] != '\t') + break; + return (i); +} + +char **remove_leading_entries(char **cmds) +{ + if (!cmds) + return (NULL); + for (int i = 0; cmds[i]; i++) + if (cmds[i][count_trailing_spaces(cmds[i])]) + return (cmds + i); + return (cmds); +} + +char *process_aliases(char *cmd, env_t *env) +{ + int bin_len; + + for (bin_len = 0; cmd[bin_len]; bin_len++) { + if (cmd[bin_len] == ' ' || cmd[bin_len] == '\t') + break; + } + for (alias_t *al = env->alias; al; al = al->next) { + if (!strncmp(al->alias, cmd, bin_len)) { + cmd = realloc(cmd, strlen(cmd) + strlen(al->command) + 1 - bin_len); + if (!cmd) + return (NULL); + rm_n_char(cmd, bin_len); + insert_substring(cmd, al->command, 1); + } + } + return (cmd); +} + +char **parse_input(char *cmd, env_t *env, wordexp_t *parser) +{ + if (!(cmd = strdup(cmd + count_trailing_spaces(cmd)))) + return (NULL); + if (!(cmd = process_vars(cmd, env))) + return (NULL); + cmd = process_aliases(cmd, env); + if (wordexp(cmd, parser, WRDE_SHOWERR)) { + perror(SHELL_NAME); + return (NULL); + } + free(cmd); + return (parser->we_wordv); +} \ No newline at end of file diff --git a/src/parser/parser_utilities.c b/src/parser/parser_utilities.c new file mode 100644 index 0000000..24b2065 --- /dev/null +++ b/src/parser/parser_utilities.c @@ -0,0 +1,90 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** parser_utilities +*/ + +#include +#include +#include "shell.h" +#include "parser.h" + +char **glob_error(char **argv, int err); + +char *strcat_realloc(char *dest, char *src) +{ + if (dest) { + dest = realloc(dest, sizeof(char) * (strlen(dest) + strlen(src) + 1)); + if (!dest) + return (NULL); + } else { + dest = malloc(sizeof(char) * (strlen(src) + 1)); + if (!dest) + return (NULL); + dest[0] = '\0'; + } + strcat(dest, src); + return (dest); +} + +char *add_to_buffer(char *buffer, char *ptr, int nb, env_t *env) +{ + char *new; + + if (nb <= 0) + return (buffer); + new = strndup(ptr, nb + 1); + if (!new) + return (NULL); + new[nb] = '\0'; + if (env) { + remove_inhibitors_symbols_n_limit(new, nb); + new = process_vars(new, env); + } + buffer = strcat_realloc(buffer, new); + free(new); + return (buffer); +} + +void remove_inhibitors_symbols_n_limit(char *str, int nb) +{ + for (int i = 0; str[i] && i < nb; i++) { + if (str[i] == '\\') { + for (int j = i; str[j]; j++) { + str[j] = str[j + 1]; + } + 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..8966453 --- /dev/null +++ b/src/parser/parser_vars_utilities.c @@ -0,0 +1,81 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#include "parser.h" +#include +#include + +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); +} + +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); +} + +void free_array(char **array) +{ + for (int i = 0; array[i]; i++) { + free(array[i]); + } + free(array); +} \ No newline at end of file diff --git a/src/parser/quotes.c b/src/parser/quotes.c new file mode 100644 index 0000000..ca0f276 --- /dev/null +++ b/src/parser/quotes.c @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2020 +** PSU_minishell2_2019 +** File description: +** redirections +*/ + +#include "parser.h" +#include + +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"); + return (-1); + } + length = (ptr_end - ptr) / sizeof(char); + *data = strndup(&ptr[1], length); + if (!(*data)) + return (-1); + (*data)[length - 1] = '\0'; + return (length); +} \ No newline at end of file diff --git a/src/prompt.c b/src/prompt.c index 5732f24..5db2dd6 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -10,6 +10,7 @@ #include "shell.h" #include "builtin.h" #include "redirections.h" +#include "parser.h" #include "utility.h" #include #include @@ -32,27 +33,27 @@ const builtin builtins[] = { {NULL, NULL} }; -int prompt_run(char *cmd, redirection *inout[2], env_t *env) +int prompt_run(char *cmd, redirection *inout[2], env_t *env, redirection *cmds) { - char **argv = get_argv(cmd); + wordexp_t parser; + char **argv = parse_input(cmd, env, &parser); + int ret = -2; - if (!argv) { - perror(SHELL_NAME); - return (-1); - } - if (!argv[0]) - return (0); - argv = globbing(argv); if (!argv) return (0); if (**argv == '!' && argv[0][1] && argv[0][1] != ' ') - return (run_builtin(&builtins[5], argv, inout, env)); + ret = run_builtin(&builtins[5], argv, inout, env); for (int i = 0; builtins[i].name; i++) if (!strcmp(argv[0], builtins[i].name)) - return (run_builtin(&builtins[i], argv, inout, env)); - run_cmd(argv, inout, env); - free(argv); - return (0); + ret = run_builtin(&builtins[i], argv, inout, env); + if (ret == -2) { + run_cmd(argv, inout, env); + ret = 0; + } + wordfree(&parser); + if (cmds) + free(cmds); + return (ret); } void prompt_prepare(buffer_t *buffer, env_t *env) diff --git a/src/redirections/redirection_manager.c b/src/redirections/redirection_manager.c index 4cfd1ab..8fa2e5c 100644 --- a/src/redirections/redirection_manager.c +++ b/src/redirections/redirection_manager.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "utility.h" #include "builtin.h" @@ -66,31 +67,32 @@ int run_with_redirections(char *cmd, env_t *env, redirection *input) inout[0] = input; inout[1] = NULL; if (!cmds || !cmds[0].type) - return (prompt_run(cmd, inout, env)); + return (prompt_run(cmd, inout, env, cmds)); for (int i = 0; cmds[i].type; i++) { if (cmds[i].type->type & INPUT) inout[0] = &cmds[i]; else inout[1] = &cmds[i]; if (cmds[i].type->type & PIPE) - return (prompt_run(cmd, inout, env)); + return (prompt_run(cmd, inout, env, cmds)); } - return (prompt_run(cmd, inout, env)); + return (prompt_run(cmd, inout, env, cmds)); } -int command_format_is_invalid(char **cmds, env_t *env, int *return_values) +bool command_format_is_invalid(char **cmds, env_t *env, int *return_values) { for (int i = 0; cmds[i]; i++) { - if (redirections_are_invalid(cmds[i])) { - env->env = my_setenv(env->vars, "?", "1"); - return (1); - } else if (split_is_invalid(cmds, return_values, i)) { - write(2, "Invalid null command.\n", 22); + if (!cmds[i] || !cmds[i][count_trailing_spaces(cmds[i])] + || split_is_invalid(cmds, return_values, i)) { + dprintf(2, "Invalid null command.\n"); env->vars = my_setenv(env->vars, "?", "1"); - return (1); + return (true); + } else if (redirections_are_invalid(cmds[i])) { + env->env = my_setenv(env->vars, "?", "1"); + return (true); } } - return (0); + return (false); } int eval_raw_cmd(char *cmd, env_t *env) @@ -99,11 +101,9 @@ int eval_raw_cmd(char *cmd, env_t *env) char **cmds = NULL; int ret = 0; - cmd = get_alias(cmd, env->alias); - if (!cmd) - return (0); return_values = get_return_separator(cmd); - cmds = split_commands(cmd); + cmds = split_str(cmd, (char *[]){";", "||", "&&", NULL}); + cmds = remove_leading_entries(cmds); if (!cmds) return (-1); if (command_format_is_invalid(cmds, env, return_values)) diff --git a/src/utility/envpath.c b/src/utility/envpath.c index f5906f5..cf0850b 100644 --- a/src/utility/envpath.c +++ b/src/utility/envpath.c @@ -28,7 +28,6 @@ char **get_envpath(env_t *env) if (pathstr) { path_cpy = strdup(pathstr); envpath = to_array(path_cpy); - free(path_cpy); } return (envpath); } \ No newline at end of file diff --git a/src/utility/eof.c b/src/utility/eof.c index 92a209b..ef2ddab 100644 --- a/src/utility/eof.c +++ b/src/utility/eof.c @@ -16,10 +16,10 @@ int get_max_eof(char *ignoreeof) bool correct = true; for (int i = 0; ignoreeof[i] && correct; i++) - if(!is_num(ignoreeof[i])) + if (!is_num(ignoreeof[i])) correct = false; if (correct && strcmp(ignoreeof, "0") && strcmp(ignoreeof, "")) - return(strtol(ignoreeof, NULL, 10)); + return (strtol(ignoreeof, NULL, 10)); return (26); } diff --git a/src/utility/split_str.c b/src/utility/split_str.c index 37eedfa..30bc132 100644 --- a/src/utility/split_str.c +++ b/src/utility/split_str.c @@ -1,36 +1,20 @@ /* ** EPITECH PROJECT, 2020 -** PSU_minishell2_2019 +** Utility ** File description: ** split_str */ +#include #include #include -#include -int ncount_char(const char *str, int end, char c) +static char *get_delimiter(char *str, char **delims) { - int count = 0; - - if (str == NULL) - return (0); - while (*str && end-- > 0) - if (*(str++) == c) - count++; - return (count); -} - -int count_char(const char *str, char c) -{ - int count = 0; - - if (str == NULL) - return (0); - while (*str) - if (*(str++) == c) - count++; - return (count); + for (int i = 0; delims[i]; i++) + if (!strncmp(str, delims[i], strlen(delims[i]))) + return (delims[i]); + return (NULL); } int count_str(char *str, char *delim) @@ -44,27 +28,42 @@ int count_str(char *str, char *delim) return (count); } -char **split_str(char *str, char delim) +static int get_splitted_count(char *str, char **delims) { - char **splited = malloc(sizeof(char *) * (count_char(str, delim) + 2)); - int i; - int j = 0; + int count = 1; + char *delim; + for (int i = 0; str[i]; i++) { + delim = get_delimiter(str + i, delims); + if (delim) { + count++; + i += strlen(delim); + } + } + return (count); +} + +char **split_str(char *str, char **delims) +{ + char **arr = malloc(sizeof(char *) * (get_splitted_count(str, delims) + 1)); + int index = 0; + int i; + char *delim; + + if (!arr) + return (NULL); for (i = 0; str[i]; i++) { - if (str[i] != delim) + if (!(delim = get_delimiter(str + i, delims))) continue; str[i] = '\0'; - if (i > 0) { - splited[j] = str; - j++; - } - str += i + 1; + arr[index] = str; + str += i + strlen(delim); + if (i > 0) + index++; i = -1; } - if (i > 0) { - splited[j] = str; - j++; - } - splited[j] = NULL; - return (splited); + // if (i > 0) + arr[index++] = str; + arr[index] = NULL; + return (arr); } \ No newline at end of file diff --git a/tests/tester/tests b/tests/tester/tests index dcbde9a..d7f5d86 100644 --- a/tests/tester/tests +++ b/tests/tester/tests @@ -332,7 +332,7 @@ NAME="933" SETUP="" CLEAN="" TESTS= - echo ' || ls' + echo ' && ls' [933-END] [934] @@ -343,14 +343,6 @@ TESTS= echo ' || ' [934-END] -[935] -NAME="935" -SETUP="" -CLEAN="" -TESTS= - echo ' && ' -[935-END] - [936] NAME="936" SETUP="" diff --git a/tests/tsource.c b/tests/tsource.c index 305be80..00f5803 100644 --- a/tests/tsource.c +++ b/tests/tsource.c @@ -15,7 +15,7 @@ Test(get_special_arg_at, at_arg) { - char **argv = split_str(strdup("source file a b c"), ' '); + char **argv = split_str(strdup("source file a b c"), (char *[]) {" ", NULL}); int argv_len = 5; char *res = NULL; @@ -26,7 +26,7 @@ Test(get_special_arg_at, at_arg) Test(get_special_arg_star, at_arg) { - char **argv = split_str(strdup("source file a b c"), ' '); + char **argv = split_str(strdup("source file a b c"), (char *[]) {" ", NULL}); int argv_len = 5; char *res = NULL;