diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c1eb5b..704702c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,10 @@ include_directories( set(CMAKE_C_STANDARD 99) set(CMAKE_C_FLAGS "-Wall -Werror -pedantic -fpic -Wextra -Wshadow") -add_subdirectory(fish_shell) +set(SOURCE_FILES fish_shell/main.c fish_shell/fish_types.h fish_shell/fish_core.h fish_shell/fish_core.c fish_shell/fish_commands.c fish_shell/fish_commands.h fish_shell/fish_globbing.c fish_shell/fish_globbing.h fish_shell/fish_utils.c fish_shell/fish_utils.h) +add_executable(fish ${SOURCE_FILES}) + +#add_subdirectory(fish_shell) add_subdirectory(fish_shell_tests) diff --git a/fish_shell/CMakeLists.txt b/fish_shell/CMakeLists.txt deleted file mode 100644 index df0e5e8..0000000 --- a/fish_shell/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(fish_shell) - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_FLAGS "-Wall -Werror -pedantic -fpic -Wextra -Wshadow") - -set(SOURCE_FILES main.c fish_types.h fish_core.h fish_core.c fish_commands.c fish_commands.h fish_globbing.c fish_globbing.h fish_utils.c fish_utils.h) -add_executable(fish ${SOURCE_FILES}) \ No newline at end of file diff --git a/fish_shell/fish_commands.c b/fish_shell/fish_commands.c index a103451..1b64373 100644 --- a/fish_shell/fish_commands.c +++ b/fish_shell/fish_commands.c @@ -3,7 +3,9 @@ // #include #include +#include #include "fish_core.h" +#include "fish_types.h" /* Necessary global variables */ char * builtinCommandsStr[] = { @@ -35,11 +37,12 @@ int fishCd(WordArray *args) { perror("fish"); } } - return 1; + return 0; } int fishHelp(WordArray *args) { int i; + args->size = args->size; printf("Bartuccio Antoine, Amalvy Arthur, Yann Chevanton\n"); printf("Tape tes putains de noms de programmes et tes arguments de merde et tabasse ENTER !\n"); printf("Les commandes suivantes sont internes :\n"); @@ -47,16 +50,13 @@ int fishHelp(WordArray *args) { printf("\t%s\n", builtinCommandsStr[i]); } printf("Et sinon pour le reste, RTFM !"); - if (args->size > 0) - return 1; - return 1; + return 0; } int fishExit(WordArray *args) { - if (args->size != 1) - return 1; - else - return 0; + args->size = args->size; + exit(EXIT_SUCCESS); + } int getNbBuiltins() { diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index 0e7f0bf..48dac22 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -9,11 +9,11 @@ #include #include "fish_core.h" #include "fish_globbing.h" +#include "fish_types.h" void fishLoop(Settings * settings){ char * line = NULL; WordList* splited = NULL; - WordArray* array = NULL; int status = 1; do { @@ -23,11 +23,10 @@ void fishLoop(Settings * settings){ splited = split(line, (char*) FISH_TOKENS); splited = fishExpand(splited); - array = wordListToWordArray(splited); - status = fishExecute(array); + status = fishExecute(splited); - freeWordArray(array); free(line); + } while(status); } @@ -124,16 +123,16 @@ void freeSettings(Settings *settings){ int fishLoad(WordArray *array) { pid_t pid; - int status; + int status = 1; pid = fork(); if (pid == 0){ /* Executes only in the child process */ if (execvp(array->words[0], array->words) == -1){ /* Error during system call */ - perror("fish"); + exit(EXIT_FAILURE); } - exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); } else if (pid < 0){ /* Fork failed */ perror("fish"); @@ -144,21 +143,66 @@ int fishLoad(WordArray *array) { do { waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + if (status) fprintf(stderr, "%s\n", getInsult()); + } + return status; +} + +int fishExecute(WordList *list) { + WordList *splited = NULL; + shell_operator op = NONE; + WordArray *array = NULL; + + splited = parseWordList(list, &op); + array = wordListToWordArray(list); + + switch (op) { + case AND: + if (!loadRightCommand(array)) fishExecute(splited); + else freeWordList(splited); + break; + case OR: + loadRightCommand(array); + fishExecute(splited); + break; + default: + loadRightCommand(array); } return 1; } -int fishExecute(WordArray *array) { +int loadRightCommand(WordArray *array){ int i; - if (array->size < 0) - return 1; - - for (i=0; i < getNbBuiltins(); i++){ - if (!strcmp(array->words[0], getBuiltinCommandsStr()[i])){ + if (array->size <= 0) return 1; + for (i = 0; i < getNbBuiltins(); i++) { + if (!strcmp(array->words[0], getBuiltinCommandsStr()[i])) { return getBuiltinCommands()[i](array); } } - return fishLoad(array); } + +WordList * parseWordList(WordList *list, shell_operator *an_operator) { + char *op_str[] = { + (char*) "&&", + (char*) "||" + }; + shell_operator op[] = { + AND, + OR + }; + WordList *newList = NULL; + int max = sizeof(op_str) / sizeof(char*); + int i = 0; + + while (i < max && newList == NULL){ + newList = splitWordList(list, op_str[i]); + i++; + } + + if (newList != NULL) *an_operator = op[i-1]; + else *an_operator = NONE; + + return newList; +} diff --git a/fish_shell/fish_core.h b/fish_shell/fish_core.h index 27a51cf..27abdc5 100644 --- a/fish_shell/fish_core.h +++ b/fish_shell/fish_core.h @@ -32,9 +32,12 @@ char * fishReadLine(); int countSeparators(char *string, char *separators); // Tested - int fishLoad(WordArray *array); -int fishExecute(WordArray *array); +int fishExecute(WordList *list); + +WordList *parseWordList(WordList *list, shell_operator *an_operator); + +int loadRightCommand(WordArray *array); #endif //FISH_FISH_CORE_H diff --git a/fish_shell/fish_types.h b/fish_shell/fish_types.h index 717d13d..59afdb7 100644 --- a/fish_shell/fish_types.h +++ b/fish_shell/fish_types.h @@ -7,6 +7,14 @@ /* Custom types */ +typedef enum { + NONE, + PIPE, + BACKGROUND_PROCESS, + AND, + OR +} shell_operator ; + typedef struct { char ** words; int size; diff --git a/fish_shell/fish_utils.c b/fish_shell/fish_utils.c index 50a5d4c..b76511a 100644 --- a/fish_shell/fish_utils.c +++ b/fish_shell/fish_utils.c @@ -6,6 +6,7 @@ #include #include #include +#include "fish_utils.h" #include "fish_types.h" void crash(){ @@ -30,7 +31,11 @@ char *getInsult(){ char *insults[] = { (char *) "Apprend à écrire crétin !", (char *) "Bolos !", - (char *) "Mois aussi je sais écrire de la merde, pourtant je le fait pas !" + (char *) "Mois aussi je sais écrire de la merde, pourtant je le fait pas !", + (char *) "Oh ! Une erreur ! Comme ta vie en fait...", + (char *) "Nul !", + (char *) "Pense à aller à l'école un jour", + (char *) "Et après on dit que c'est la faute de l'ordinateur..." }; if (!init){ srand((unsigned int) time(NULL)); @@ -84,20 +89,11 @@ void addWordList(WordList *list, char *word) { } void removeWordList(WordList *list) { - WordListElement *current = list->last; - if (current != NULL){ - list->last = current->previous; - if (current->previous != NULL) - current->previous->next = NULL; - if (current->word != NULL) - free(current->word); - free(current); - list->size--; - } + if (list != NULL) removeWordListElem(list, list->last); } void freeWordList(WordList *list) { - while (list->size != 0) + while (list != NULL && list->size != 0) removeWordList(list); free(list); } @@ -138,3 +134,76 @@ WordList *wordArrayToWordList(WordArray *array) { return list; } + +void removeWordListElem(WordList *list, WordListElement *elem) { + if (list != NULL && elem != NULL){ + + if (list->first == elem && list->last == elem){ + list->first = NULL; + list->last = NULL; + + } else if (list->first == elem){ + list->first = elem->next; + elem->previous = NULL; + + } else if (list->last == elem){ + list->last = elem->previous; + elem->previous->next = NULL; + + } else { + elem->next->previous = elem->previous; + elem->previous->next = elem->next; + } + + list->size--; + + if (elem->word != NULL) + free(elem->word); + + free(elem); + } +} + +WordList *sliceWordList(WordList *list, int min_index, int max_index) { + WordList *newList = createWordList(); + WordListElement *elem = NULL; + WordListElement *tmp = NULL; + int i=0; + + if (list == NULL || min_index > list->size || max_index > list->size) return newList; + else { + elem = list->first; + while (i < max_index){ + + tmp = elem->next; + if (i >= min_index){ + addWordList(newList, elem->word); + removeWordListElem(list, elem); + } + + elem = tmp; + + i++; + } + } + return newList; +} + +WordList *splitWordList(WordList *list, char *token) { + WordList * newList = NULL; + WordListElement * current = list->first; + int i = 0; + + while (current != NULL){ + if (!strcmp(current->word, token)){ + newList = sliceWordList(list, i + 1, list->size); + removeWordListElem(list, current); + current = NULL; + } + else current = current->next; + i++; + } + + return newList; +} + diff --git a/fish_shell/fish_utils.h b/fish_shell/fish_utils.h index 5aec4eb..5f792f6 100644 --- a/fish_shell/fish_utils.h +++ b/fish_shell/fish_utils.h @@ -15,14 +15,20 @@ void freeWordArray(WordArray *array); // Tested WordList * createWordList(); // Tested +WordList * sliceWordList(WordList *list, int min_index, int max_index); + void addWordList(WordList *list, char *word); // Tested void removeWordList(WordList *list); // Tested +void removeWordListElem(WordList *list, WordListElement *elem); + void freeWordList(WordList *list); // Tested WordArray * wordListToWordArray(WordList *list); // Tested WordList * wordArrayToWordList(WordArray * array); // Tested +WordList * splitWordList(WordList *list, char * tokens); + #endif //FISH_FISH_UTILS_H