From 9c13c2776751c61d353c7024ec003843d5ba05c9 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 24 May 2020 20:10:59 +0200 Subject: [PATCH 1/2] if one liners working, need to check the syntax of the expression though, will do later --- Makefile | 2 + include/builtin.h | 8 ++- src/builtin/builtin_if.c | 77 +++++++++++++++++++++++ src/builtin/builtin_if_two.c | 46 ++++++++++++++ src/env.c | 1 - src/key_bindings/basic_typing_functions.c | 2 +- src/prompt.c | 1 + 7 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/builtin/builtin_if.c create mode 100644 src/builtin/builtin_if_two.c diff --git a/Makefile b/Makefile index 2ba4963..f654aad 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ SRC = src/shell.c \ src/builtin/builtin_alias.c \ src/builtin/builtin_unalias.c \ src/builtin/builtin_echo.c \ + src/builtin/builtin_if.c \ + src/builtin/builtin_if_two.c \ src/signal.c \ src/free_env.c \ src/utility/same_var.c \ diff --git a/include/builtin.h b/include/builtin.h index 8682de1..0285cec 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -29,6 +29,7 @@ int builtin_history(char **args, env_t *env); int builtin_alias(char **args, env_t *env); int builtin_unalias(char **args, env_t *env); int builtin_echo(char **args, env_t *env); +int builtin_if(char **argv, env_t *env); //utility bool find_path_in_builtins(char *cmd); char **get_envpath(env_t *env); @@ -58,4 +59,9 @@ int add_alias_to_list(alias_t **list, alias_t *elem, char *alias); void remove_alias(char *alias, alias_t **list); //echo -int print_char(char *str, int i); \ No newline at end of file +int print_char(char *str, int i); + +//if + +int get_test_return_value(char **argv, env_t *env); +int get_max_cmd_len(char **argv); \ No newline at end of file diff --git a/src/builtin/builtin_if.c b/src/builtin/builtin_if.c new file mode 100644 index 0000000..131915b --- /dev/null +++ b/src/builtin/builtin_if.c @@ -0,0 +1,77 @@ +/* +** EPITECH PROJECT, 2020 +** 42sh +** File description: +** if builtin +*/ + +#include +#include +#include +#include "shell.h" +#include "builtin.h" + +int get_max_cmd_len(char **argv) +{ + int len = 0; + + for (int i = 0; argv[i]; i++) { + if (i) + len++; + for (int j = 0; argv[i][j]; j++) + len++; + } + return (len); +} + +int execute_one_liner(char **argv, env_t *env) +{ + bool after_exp = false; + char *cmd = malloc(sizeof(char) * get_max_cmd_len(argv)); + int counter = 0; + + if (!cmd || get_test_return_value(argv, env)) + return (0); + for (int i = 0; argv[i]; i++) { + for (int j = 0; argv[i][j]; j++) { + if (after_exp) + cmd[counter++] = argv[i][j]; + if (argv[i][j] == ')') + after_exp = true; + } + if (after_exp && counter) + cmd[counter++] = ' '; + } + cmd[counter] = 0; + eval_raw_cmd(cmd, env); + free(cmd); + return (0); +} + +int is_valid_expression(char **argv) +{ + int len = 0; + + for (; argv[len]; len++); + if (len < 1) + return (0); + if (argv[1][0] != '(') + return (0); + for (int i = 1; argv[i]; i++) + for (int j = 0; argv[i][j]; j++) + if (argv[i][j] == ')') + return (1); + return (0); +} + +int builtin_if(char **argv, env_t *env) +{ + if (is_valid_expression(argv)) { + execute_one_liner(argv, env); + } else { + printf("if: Expression Syntax.\n"); + fflush(stdout); + env->vars = my_setenv(env->vars, "?", "1"); + } + return (0); +} \ No newline at end of file diff --git a/src/builtin/builtin_if_two.c b/src/builtin/builtin_if_two.c new file mode 100644 index 0000000..14f93e3 --- /dev/null +++ b/src/builtin/builtin_if_two.c @@ -0,0 +1,46 @@ +/* +** EPITECH PROJECT, 2020 +** 42sh +** File description: +** builtin_if_two +*/ + +#include +#include +#include "shell.h" +#include "builtin.h" + +char *get_expr(char **argv) +{ + bool in_expr = false; + char *res = malloc(sizeof(char) * get_max_cmd_len(argv) + 5); + int counter = 5; + + if (!res) return (NULL); + strcpy(res, "test "); + for (int i = 0; argv[i]; i++) { + for (int j = 0; argv[i][j]; j++) { + if (argv[i][j] == ')') + in_expr = false; + if (in_expr) + res[counter++] = argv[i][j]; + if (argv[i][j] == '(') + in_expr = true; + } + if (in_expr && counter) + res[counter++] = ' '; + } + res[counter] = 0; + return (res); +} + +int get_test_return_value(char **argv, env_t *env) +{ + int res = 0; + char *exp = get_expr(argv); + + eval_raw_cmd(exp, env); + res = my_getenv(env->vars, "?") ? atoi(my_getenv(env->vars, "?")) : 1; + free(exp); + return (res); +} \ No newline at end of file diff --git a/src/env.c b/src/env.c index 66d618e..c100729 100644 --- a/src/env.c +++ b/src/env.c @@ -10,7 +10,6 @@ #include #include "utility.h" - char *my_getenv(char **env, char *name) { if (!env) diff --git a/src/key_bindings/basic_typing_functions.c b/src/key_bindings/basic_typing_functions.c index 3b9490a..eef6c91 100644 --- a/src/key_bindings/basic_typing_functions.c +++ b/src/key_bindings/basic_typing_functions.c @@ -58,7 +58,7 @@ int delete_char_command(int key, buffer_t *buffer, env_t *env) int newline_command(int key, buffer_t *buffer, env_t *env) { - int ret; + int ret = 0; env->vars = my_unsetenv(env->vars, "eof"); if (env->window) diff --git a/src/prompt.c b/src/prompt.c index 860201e..ede631f 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -28,6 +28,7 @@ const builtin builtins[] = { {"alias", &builtin_alias}, {"unalias", &builtin_unalias}, {"echo", &builtin_echo}, + {"if", &builtin_if}, {NULL, NULL} }; From 23fd5258745d9799c9503ae7c2028aea59437769 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 24 May 2020 21:51:25 +0200 Subject: [PATCH 2/2] error handling --- include/builtin.h | 2 +- src/builtin/builtin_if.c | 45 ++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/builtin.h b/include/builtin.h index 0285cec..54694b3 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -62,6 +62,6 @@ void remove_alias(char *alias, alias_t **list); int print_char(char *str, int i); //if - +char *get_expr(char **argv); int get_test_return_value(char **argv, env_t *env); int get_max_cmd_len(char **argv); \ No newline at end of file diff --git a/src/builtin/builtin_if.c b/src/builtin/builtin_if.c index 131915b..de55c14 100644 --- a/src/builtin/builtin_if.c +++ b/src/builtin/builtin_if.c @@ -11,6 +11,25 @@ #include "shell.h" #include "builtin.h" +int matched_parenthesis(char **argv) +{ + int left_p = 0; + int right_p = 0; + + for (int i = 0; argv[i]; i++) + for (int j = 0; argv[i][j]; j++) { + left_p = argv[i][j] == '(' ? left_p + 1 : left_p; + right_p = argv[i][j] == ')' ? right_p + 1 : right_p; + } + if (left_p > right_p) + printf("Too many ('s.\n"); + if (right_p > left_p) + printf("Too many )'s.\n"); + if (left_p == right_p) + return (1); + return (0); +} + int get_max_cmd_len(char **argv) { int len = 0; @@ -48,30 +67,30 @@ int execute_one_liner(char **argv, env_t *env) return (0); } -int is_valid_expression(char **argv) +int is_valid_if_cmd(char **argv) { int len = 0; for (; argv[len]; len++); - if (len < 1) + if (len < 1) { + printf("if: Too few arguments\n"); return (0); - if (argv[1][0] != '(') + } + if (!matched_parenthesis(argv)) return (0); - for (int i = 1; argv[i]; i++) - for (int j = 0; argv[i][j]; j++) - if (argv[i][j] == ')') - return (1); - return (0); + if (argv[1][0] != '(') { + printf("if: Expression Syntax.\n"); + return (0); + } + return (1); } int builtin_if(char **argv, env_t *env) { - if (is_valid_expression(argv)) { + if (is_valid_if_cmd(argv)) { execute_one_liner(argv, env); - } else { - printf("if: Expression Syntax.\n"); - fflush(stdout); + env->vars = my_setenv(env->vars, "?", "0"); + } else env->vars = my_setenv(env->vars, "?", "1"); - } return (0); } \ No newline at end of file