diff --git a/include/commands.h b/include/commands.h index 84355e20c28ea7db7cb2edc74add1e08e711b89a..7fbe4d9777458b930b91719f6bceeaff6156fa80 100644 --- a/include/commands.h +++ b/include/commands.h @@ -7,4 +7,8 @@ struct single_command char** argv; }; +int evaluate_command(int n_commands, struct single_command (*commands)[]); + +void free_commands(int n_commands, struct single_command (*commands)[]); + #endif // MYSH_COMMANDS_H_ diff --git a/src/built_in.c b/src/built_in.c index 5c7964915cadc5784ee73cff8053bc9a9424899d..9a466e91501d5877107fb67e308275c4847bcb38 100644 --- a/src/built_in.c +++ b/src/built_in.c @@ -61,7 +61,7 @@ int validate_pwd_argv(int argc, char** argv) { } int validate_fg_argv(int argc, char** argv) { - if (argv != 1) return 0; + if (argc != 1) return 0; if (strcmp(argv[0], "fg") != 0) return 0; return 1; diff --git a/src/commands.c b/src/commands.c index ef5f4b9ca3b9370c093edc42bb1450821227214d..2a4e6eccf7c1efd74825114ee6b2f08894d0fc96 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1,10 +1,76 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + #include "commands.h" #include "built_in.h" -struct built_in_command built_in_commands[] = { +static struct built_in_command built_in_commands[] = { { "cd", do_cd, validate_cd_argv }, { "pwd", do_pwd, validate_pwd_argv }, { "fg", do_fg, validate_fg_argv } }; +static int is_built_in_command(const char* command_name) +{ + static const int n_built_in_commands = sizeof(built_in_commands) / sizeof(built_in_commands[0]); + + for (int i = 0; i < n_built_in_commands; ++i) { + if (strcmp(command_name, built_in_commands[i].command_name) == 0) { + return i; + } + } + + return -1; // Not found +} + +/* + * Description: Currently this function only handles single built_in commands. You should modify this structure to launch process and offer pipeline functionality. + */ +int evaluate_command(int n_commands, struct single_command (*commands)[]) +{ + if (n_commands > 0) { + struct single_command* com = (*commands); + + assert(com->argc != 0); + + int built_in_pos = is_built_in_command(com->argv[0]); + if (built_in_pos != -1) { + if (built_in_commands[built_in_pos].command_validate(com->argc, com->argv)) { + if (built_in_commands[built_in_pos].command_do(com->argc, com->argv) != 0) { + fprintf(stderr, "%s: Error occurs\n", com->argv[0]); + } + } else { + fprintf(stderr, "%s: Invalid arguments\n", com->argv[0]); + return -1; + } + } else if (strcmp(com->argv[0], "") == 0) { + return 0; + } else if (strcmp(com->argv[0], "exit") == 0) { + return 1; + } else { + fprintf(stderr, "%s: command not found\n", com->argv[0]); + return -1; + } + } + + return 0; +} + +void free_commands(int n_commands, struct single_command (*commands)[]) +{ + for (int i = 0; i < n_commands; ++i) { + struct single_command *com = (*commands) + i; + int argc = com->argc; + char** argv = com->argv; + + for (int j = 0; j < argc; ++j) { + free(argv[j]); + } + + free(argv); + } + memset((*commands), 0, sizeof(struct single_command) * n_commands); +} diff --git a/src/main.c b/src/main.c index 18697a3e73f4e97b6f5449f25df348c2eac92418..77c78049273e013e278ad9021fa088531b636a97 100644 --- a/src/main.c +++ b/src/main.c @@ -17,40 +17,14 @@ int main() int n_commands = 0; mysh_parse_command(buf, &n_commands, &commands); - for (int i = 0; i < n_commands; ++i) { - struct single_command* com = commands + i; - int argc = com->argc; - char** argv = com->argv; - for (int j = 0; j < argc; ++j) { - printf("%s ", argv[j]); - } - printf("\n"); - } + int ret = evaluate_command(n_commands, &commands); + + free_commands(n_commands, &commands); + n_commands = 0; - /* - - if (strcmp(argv[0], "") == 0) { - goto release_and_continue; - } else if (strcmp(argv[0], "cd") == 0) { - if (do_cd(argc, argv)) { - fprintf(stderr, "cd: Invalid arguments\n"); - } - } else if (strcmp(argv[0], "pwd") == 0) { - if (do_pwd(argc, argv)) { - fprintf(stderr, "pwd: Invalid arguments\n"); - } - } else if (strcmp(argv[0], "exit") == 0) { - goto release_and_exit; - } else { - fprintf(stderr, "%s: command not found\n", argv[0]); + if (ret == 1) { + break; } -release_and_continue: - release_argv(argc, &argv); - continue; -release_and_exit: - release_argv(argc, &argv); - break; - */ } return 0; diff --git a/src/utils.c b/src/utils.c index 75958f46eb3d95cb3fa882711508a80dd18a51df..6fbc970d8bb0840c88240f73cdc330414d4cd680 100644 --- a/src/utils.c +++ b/src/utils.c @@ -33,6 +33,8 @@ void parse_single_command(const char* command, { const int kMaxArgc = 512; *argv = (char**)malloc(kMaxArgc * sizeof(char*)); + for (int i = 0; i < kMaxArgc; ++i) + (*argv)[i] = NULL; char buf[4096]; strcpy(buf, command);