diff --git a/include/operator.h b/include/operator.h index 25cb99c..9369029 100644 --- a/include/operator.h +++ b/include/operator.h @@ -7,38 +7,21 @@ #ifndef OPERATOR_H #define OPERATOR_H -#include +#include #include "typedef.h" -/** - * The list of operators that can be used -*/ -extern const char *operators[]; - -/** - * The number of operators that can be used -*/ -extern const int num_operators; - -/** - * @brief Checks if the given token is an operator - * @param token The token to be checked - * @return 1 if the token is an operator, 0 otherwise -*/ -int is_operator(const char *token); - /** * @brief Gets the type of the given operator * @param operator_str The operator string * @return The type of the operator -*/ + */ OperatorType get_operator_type(const char *operator_str); /** - * @brief Gets the string representation of the given operator - * @param op The operator - * @return The string representation of the operator -*/ -const char *get_operator_string(OperatorType op); + * @brief Gets the string corresponding to the given operator + * @param operator_type The operator type + * @return The string corresponding to the operator + */ +const char *get_operator_string(OperatorType operator_type); -#endif //OPERATOR_H +#endif // OPERATOR_H diff --git a/src/command_sequence.c b/src/command_sequence.c index bd351fd..d98a170 100644 --- a/src/command_sequence.c +++ b/src/command_sequence.c @@ -1,8 +1,9 @@ #include "command_sequence.h" -void command_sequence_init(char *input) { +void command_sequence_init(char *input) +{ const char *delimeters = " \n"; - + char *commands[MAX_COMMANDS]; char *operators[MAX_OPERATORS]; @@ -16,8 +17,10 @@ void command_sequence_init(char *input) { sequence.num_commands = 0; char *token = strtok(input, delimeters); - while (token != NULL) { - if(command_count >= MAX_COMMANDS) { + while (token != NULL) + { + if (command_count >= MAX_COMMANDS) + { print_info("livl-shell$ is informing you that only the three first commands will be executed. Limit of commands reached."); break; } @@ -25,19 +28,22 @@ void command_sequence_init(char *input) { process_token(token, commands, operators, ¤tCommand, &command_count, &operator_count); token = strtok(NULL, delimeters); - if (token == NULL || is_operator(token)) { + if (token == NULL || get_operator_type(token) != UNKNOWN) + { store_command(commands, ¤tCommand, &command_count); } } // Build the command sequence with its commands - for (int i = 0; i < command_count; i++) { + for (int i = 0; i < command_count; i++) + { sequence.commands[sequence.num_commands++] = evaluate_command(commands[i]); free(commands[i]); } // Build the command sequence with its operators - for (int i = 0; i < operator_count; i++) { + for (int i = 0; i < operator_count; i++) + { sequence.operators[i] = strdup(operators[i]); free(operators[i]); } @@ -46,27 +52,33 @@ void command_sequence_init(char *input) { int result = execute_command_sequence(&sequence); - if (result < 0) { + if (result < 0) + { fprintf(stderr, "An error occurred while executing the commands\n"); } free_command_sequence(&sequence); } - -void process_token(char *token, char **commands, char **operators, char **currentCommand, int *cmdIndex, int *opIndex) { - if (is_operator(token)) { +void process_token(char *token, char **commands, char **operators, char **currentCommand, int *cmdIndex, int *opIndex) +{ + if (get_operator_type(token) != UNKNOWN) + { operators[(*opIndex)++] = strdup(token); return; - } - + } + // Token is a command - if (*currentCommand == NULL) { + if (*currentCommand == NULL) + { *currentCommand = strdup(token); - } else { + } + else + { size_t len = strlen(*currentCommand) + strlen(token) + 2; - char* temp = realloc(*currentCommand, len); - if (temp == NULL) { + char *temp = realloc(*currentCommand, len); + if (temp == NULL) + { perror("realloc"); return; } @@ -74,18 +86,21 @@ void process_token(char *token, char **commands, char **operators, char **curren strcat(*currentCommand, " "); strcat(*currentCommand, token); } - } -void store_command(char **commands, char **currentCommand, int *cmdIndex) { - if (*currentCommand != NULL) { +void store_command(char **commands, char **currentCommand, int *cmdIndex) +{ + if (*currentCommand != NULL) + { commands[(*cmdIndex)++] = *currentCommand; *currentCommand = NULL; } } -void free_command_sequence(CommandSequence *sequence) { - for (int i = 0; i < sequence->num_commands; ++i) { +void free_command_sequence(CommandSequence *sequence) +{ + for (int i = 0; i < sequence->num_commands; ++i) + { free_command(&sequence->commands[i]); } free(sequence->commands); diff --git a/src/input_parser.c b/src/input_parser.c index e03392c..db90987 100644 --- a/src/input_parser.c +++ b/src/input_parser.c @@ -3,40 +3,49 @@ #include "input_parser.h" #include "history_command.h" -char* read_input() { - char* input = malloc(MAX_INPUT_LENGTH * sizeof(char)); - if (input == NULL) { +char *read_input() +{ + char *input = malloc(MAX_INPUT_LENGTH * sizeof(char)); + if (input == NULL) + { perror("malloc"); return NULL; } - if (fgets(input, MAX_INPUT_LENGTH, stdin) == NULL) { + if (fgets(input, MAX_INPUT_LENGTH, stdin) == NULL) + { perror("fgets"); free(input); return NULL; } size_t len = strlen(input); - if (len > 0 && input[len - 1] == '\n') { + if (len > 0 && input[len - 1] == '\n') + { input[len - 1] = '\0'; } return input; } -int is_all_whitespace(const char* input) { - for (int i = 0; i < strlen(input); i++) { - if (!isspace(input[i])) { +int is_all_whitespace(const char *input) +{ + for (int i = 0; i < strlen(input); i++) + { + if (!isspace(input[i])) + { return 0; } } return 1; } -void preprocess_input(char* input) { - char* new_input = malloc(strlen(input) * 2 + 1); // Allocate enough space for the new input +void preprocess_input(char *input) +{ + char *new_input = malloc(strlen(input) * 2 + 1); // Allocate enough space for the new input - if (new_input == NULL) { + if (new_input == NULL) + { perror("malloc"); return; } @@ -44,23 +53,27 @@ void preprocess_input(char* input) { int j = 0; // Iterate over the input and add spaces around the operators - for (int i = 0; i < strlen(input); i++) { - int found = 0; + for (int i = 0; i < strlen(input); i++) + { - // Check if the current character is an operator - for (int k = 0; k < num_operators; k++) { - // strncmp compares the first n characters of two strings - if (strncmp(&input[i], operators[k], strlen(operators[k])) == 0) { - new_input[j++] = ' '; - strncpy(&new_input[j], &input[i], strlen(operators[k])); - j += strlen(operators[k]); - new_input[j++] = ' '; - i += strlen(operators[k]) - 1; - found = 1; - break; - } + char token[2] = {input[i], input[i + 1]}; + OperatorType operator_type = get_operator_type(&token); + + if (operator_type != UNKNOWN) + { + + char *operator_string = get_operator_string(operator_type); + int operator_length = strlen(get_operator_string(operator_type)); + + new_input[j++] = ' '; + strncpy(&new_input[j], operator_string, operator_length); + j += operator_length; + new_input[j++] = ' '; + i += operator_length - 1; + continue; } - if (!found) { + else + { new_input[j++] = input[i]; } } @@ -68,4 +81,3 @@ void preprocess_input(char* input) { strcpy(input, new_input); free(new_input); } - diff --git a/src/operator.c b/src/operator.c index 3215de0..394ae74 100644 --- a/src/operator.c +++ b/src/operator.c @@ -2,43 +2,91 @@ /** * Order by operator length (longest first) to avoid matching << when looking for < -*/ -const char *operators[] = { - "&&", - "||", - ">>", - "<<", - ";", - "|", - "&", - "<", - ">", -}; - -const int num_operators = sizeof(operators) / sizeof(char*); - -int is_operator(const char *token) { - for (int i = 0; i < num_operators; i++) { - if (strcmp(token, operators[i]) == 0) { - return 1; // The token is an operator - } - } - - return 0; // The token is not an operator -} + */ +OperatorType get_operator_type(const char *operator_str) +{ + + if (operator_str == NULL) + { + return UNKNOWN; + } + + size_t len = 2; + + if (strncmp(operator_str, "&&", len) == 0) + { + return AND; + } + + if (strncmp(operator_str, "||", len) == 0) + { + return OR; + } + + if (strncmp(operator_str, ">>", len) == 0) + { + return REDIRECTION_APPEND_OUTPUT; + } + + if (strncmp(operator_str, "<<", len) == 0) + { + return REDIRECTION_APPEND_INPUT; + } -OperatorType get_operator_type(const char *operator_str) { - for (int i = 0; i < num_operators; i++) { - if (strcmp(operator_str, operators[i]) == 0) { - return (OperatorType)i; - } + len = 1; + + if (strncmp(operator_str, ";", len) == 0) + { + return SEMICOLON; + } + + if (strncmp(operator_str, "|", len) == 0) + { + return PIPE; + } + + if (strncmp(operator_str, "&", len) == 0) + { + return BACKGROUND; + } + + if (strncmp(operator_str, ">", len) == 0) + { + return REDIRECTION_OUTPUT; + } + + if (strncmp(operator_str, "<", len) == 0) + { + return REDIRECTION_INPUT; } + return UNKNOWN; } -const char *get_operator_string(OperatorType op) { - if (op >= 0 && op < num_operators) { - return operators[op]; +const char *get_operator_string(OperatorType operator_type) +{ + + switch (operator_type) + { + case AND: + return "&&"; + case OR: + return "||"; + case REDIRECTION_APPEND_OUTPUT: + return ">>"; + case REDIRECTION_APPEND_INPUT: + return "<<"; + case SEMICOLON: + return ";"; + case PIPE: + return "|"; + case BACKGROUND: + return "&"; + case REDIRECTION_OUTPUT: + return ">"; + case REDIRECTION_INPUT: + return "<"; + default: + return "UNKNOWN"; } - return "UNKNOWN"; -} +} \ No newline at end of file