diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c new file mode 100644 index 0000000..a6c1aa3 --- /dev/null +++ b/src/cmd/cmd.c @@ -0,0 +1,9 @@ +#include "./cmd.h" + +void cmd_del(void *ptr) +{ + cmd* content = ptr; + + tab_free((void**)content->args); + free(content->executable); +} diff --git a/src/cmd/cmd.h b/src/cmd/cmd.h index 5a59e48..c490714 100644 --- a/src/cmd/cmd.h +++ b/src/cmd/cmd.h @@ -1,5 +1,10 @@ #pragma once +#include +#include + +#include "../../lib/bozolib/bozolib.h" + typedef struct s_cmd { char *executable; @@ -8,3 +13,7 @@ typedef struct s_cmd int fd_out; int pid; } cmd; + +void cmd_del(void* ptr); + +lst** cmds_init(size_t len); diff --git a/src/cmd/cmds.c b/src/cmd/cmds.c new file mode 100644 index 0000000..4679e26 --- /dev/null +++ b/src/cmd/cmds.c @@ -0,0 +1,34 @@ +#include "./cmd.h" +#include +#include + +lst** cmds_init(size_t len) +{ + lst** root; + lst* current; + cmd* content; + + root = calloc(sizeof(lst*), 1); + if (root == NULL) + return (NULL); + for (size_t i = 0; i < len; i++) + { + current = malloc(sizeof(lst)); + if (current == NULL) + { + lst_clear(root, &free); + free(root); + return (NULL); + } + lst_addback(root, current); + content = malloc(sizeof(cmd)); + if (content == NULL) + { + lst_clear(root, &free); + free(root); + return (NULL); + } + current->content = content; + } + return (root); +} diff --git a/src/exec/exec.c b/src/exec/exec.c index 5278c24..c5a3540 100644 --- a/src/exec/exec.c +++ b/src/exec/exec.c @@ -79,25 +79,29 @@ int execute(cmd* input, lst** env) return exitcode; } -int command_list_exec(cmd** cmds, lst** env) +int cmds_list_exec(lst** cmds, lst** env) { - int fds[2]; - for (int i=0; cmds[i] != NULL; i++) - { - if (pipe(fds) < 0) - return 1; - if (i < len((void**)cmds)-1) - { - cmds[i]->fd_out = fds[1]; - cmds[i+1]->fd_in = fds[0]; - } - if (builtin_execute(cmds[i], env) == 1) - execute(cmds[i], env); - } - return 0; + lst* current = *cmds; + cmd* content; + int fds[2]; + while (current != NULL) + { + content = current->content; + if (pipe(fds) < 0) + return 1; + if (current->next != NULL) + { + content->fd_out = fds[1]; + ((cmd*)current->next->content)->fd_in = fds[0]; + } + if (builtin_execute(content, env) == 1) + execute(content, env); + current = current->next; + } + return 0; } -char* get_executable_path(char* executable, lst** env) +char* get_executable_path(const char* executable, lst** env) { int size_path_str; char * path_file; diff --git a/src/exec/exec.h b/src/exec/exec.h index 3b8710c..2773607 100644 --- a/src/exec/exec.h +++ b/src/exec/exec.h @@ -1,7 +1,9 @@ #pragma once -int command_list_exec(cmd** cmds, lst** env); +#include "../cmd/cmd.h" +#include "../../lib/bozolib/bozolib.h" + +int cmds_list_exec(lst** cmds, lst** env); int execute(cmd* input, lst** env); int builtin_execute(cmd* input, lst** env); -int piper(cmd** cmds, lst** env); -char* get_executable_path(char* executable, lst** env); +char* get_executable_path(const char* executable, lst** env); diff --git a/src/main.c b/src/main.c index 9141161..07b15ee 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,23 @@ #include "./env/env.h" #include "./input/input.h" +#include #include #include "cmd/cmd.h" #include "./exec/exec.h" +#include "./parsing/parsing.h" + +void cmds_list_destroyer(lst*** cmds_list) +{ + for (size_t i = 0; cmds_list[i] != NULL; i++) + lst_clear(cmds_list[i], &cmd_del); + free(cmds_list); +} int main(int ac, char **av, char **env_str) { char *line; lst** env; + lst*** cmds_list; (void) av; (void) ac; @@ -17,7 +27,22 @@ int main(int ac, char **av, char **env_str) line = get_user_input(env); while (line != NULL) { + cmds_list = parsing(line, env); free(line); + if (cmds_list == NULL) + { + lst_clear(env, &env_del); + return 1; + } + for (size_t i = 0; cmds_list[i] != NULL; i++) + { + if (cmds_list_exec(cmds_list[i], env)) + { + lst_clear(env, &env_del); + return 1; + } + } + cmds_list_destroyer(cmds_list); line = get_user_input(env); } lst_clear(env, &env_del); diff --git a/src/parsing/parsing.c b/src/parsing/parsing.c new file mode 100644 index 0000000..bcb26fd --- /dev/null +++ b/src/parsing/parsing.c @@ -0,0 +1,79 @@ +#include "../cmd/cmd.h" +#include "../utils/utils.h" +#include "../exec/exec.h" +#include "../../lib/bozolib/bozolib.h" +#include + +char* parsing_executable(const char* executable, lst** env) +{ + if (strchr("./", executable[0])) + return strdup(executable); + return (get_executable_path(executable, env)); +} + +int parsing_cmd(char *str, cmd* command, lst** env) +{ + // if (get_redirections(str, command)) + // return 1; + // remove_redirections(str); + command->args = split_quoted_charset(str, "\t "); + if (command->args == NULL) + return 1; + for (size_t i = 0; command->args[i]; i++) + quote_remover(command->args[i]); + command->executable = parsing_executable(command->args[0], env); + return 0; +} + +lst **parsing_pipe(const char *str, lst** env) +{ + char** cmds_str; + lst** cmds; + lst* current; + + cmds_str = split_quoted_charset(str, "|"); + if (cmds_str == NULL) + return (NULL); + cmds = cmds_init(tablen((const void**)cmds_str)); + if (cmds == NULL) + { + tab_free((void**)cmds_str); + return (NULL); + } + current = *cmds; + for (size_t i = 0; cmds_str[i] != NULL; i++) + { + parsing_cmd(cmds_str[i], current->content, env); + current = current->next; + } + return (cmds); +} + +lst*** parsing(const char *line, lst** env) +{ + char** line_commas; + lst*** tab; + + line_commas = split_quoted_charset(line, ";"); + if (line_commas == NULL) + return (NULL); + tab = malloc(sizeof(lst**) * (tablen((const void**) line_commas) + 1)); + if (tab == NULL) + { + tab_free((void **) line_commas); + return (NULL); + } + size_t i; + for (i = 0; line_commas[i] != NULL; i++) + { + tab[i] = parsing_pipe(line_commas[i], env); + if (tab[i] == NULL) + { + tab_free((void**) line_commas); + return (NULL); + } + } + tab[i] = NULL; + return (tab); +} + diff --git a/src/parsing/parsing.h b/src/parsing/parsing.h new file mode 100644 index 0000000..cd5c9bb --- /dev/null +++ b/src/parsing/parsing.h @@ -0,0 +1,4 @@ +#pragma once +#include "../../lib/bozolib/bozolib.h" + +lst*** parsing(const char* str, lst** env); diff --git a/src/redirection/redirection.c b/src/redirection/redirection.c new file mode 100644 index 0000000..44bc1f8 --- /dev/null +++ b/src/redirection/redirection.c @@ -0,0 +1,3 @@ +#include "../../lib/bozolib/bozolib.h" + + diff --git a/src/utils/quote_remover.c b/src/utils/quote_remover.c new file mode 100644 index 0000000..d1786a8 --- /dev/null +++ b/src/utils/quote_remover.c @@ -0,0 +1,38 @@ +#include "utils.h" + +static void remove_quote_and_reset(char *str, ssize_t *start, ssize_t *stop) +{ + str_shift(str + *start, -1); + str_shift(str + *stop - 1, -1); + *start = -1; + *stop = -1; +} + +void quote_remover(char *str) +{ + size_t i; + ssize_t start; + ssize_t stop; + + start = -1; + stop = -1; + i = 0; + while (str[i] != '\0') + { + if ((str[i] == '\"' || str[i] == '\'')) + { + if (start == -1) + start = i; + else if (str[i] == str[start]) + stop = i; + } + if (stop != -1) + { + remove_quote_and_reset(str, &start, &stop); + i = i - 1; + } + else + i++; + } +} + diff --git a/src/utils/utils.h b/src/utils/utils.h index 19a40ce..eb683f0 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -1,6 +1,11 @@ #pragma once + #include +#include #include +#include "../../lib/bozolib/bozolib.h" + int is_in_quote(const char *str, size_t pos); +void quote_remover(char *str); char **split_quoted_charset(const char *str, const char *charset);