/* * File: parser.c * Author: Arthur Brandao * * Created on 31 octobre 2018 */ #include #include #include "parser.h" /* --- Fonctions privées --- */ int nb_commands(char* line){ //Initialisation variable int compteur = 0; //Parcours chaine pour chercher séparateur et compter le nombre de commande while(*line){ //Si un ; if(*line == ';'){ compteur++; } //Si | ou || else if(*line == '|'){ //Verif que ce n'est pas le dernier carac if(*(line + 1) == '\0'){ return SHELL_ERR; } //Si un || on avance de 1 en plus else if(*(line + 1) == '|'){ //Si à la fin de la chaine if(*(line + 2) == '\0'){ return SHELL_ERR; } line++; } compteur++; } //Si un && if(*line == '&'){ //Si celui d'apres est bien un && if(*(line + 1) == '&'){ line++; compteur++; } //Sinon il doit y avoir un vide pour etre le & du bck else if(*(line + 1) != '\0'){ return SHELL_ERR; } } line++; } //Ajoute la dernière commande compteur++; return compteur; } /** * Recup la 1er commande * @param c Structure commande à initialiser * @param line Ligne avec la commande * @return int Le décallage à effectuer dans line */ int get_command(Command* c, char* line){ //Declaration variable char* deb = line, * old; int length = 0, separator = 0, next = SHELL_NONE; //Parcours chaine pour chercher un séparateur while(*line){ //Si un ; if(*line == ';'){ separator = 1; break; } //Si | ou || else if(*line == '|'){ //Si 1 ou 2 | if(*(line + 1) == '|'){ separator = 2; next = SHELL_ELSE; } else { separator = 1; next = SHELL_PIPE; } break; } //Si un && if(*line == '&'){ //Si celui d'apres est bien un && if(*(line + 1) == '&'){ separator = 2; next = SHELL_IF; break; } } length++; line++; } //Verif si c'est la dernière commande if(!*line){ next = SHELL_END; } //Allocation memoire et copie chaine c->cmd = malloc(sizeof(char) * (length + 1)); strncpy(c->cmd, deb, length); c->next = next; c->argc = 0; //Trim et supprime l'ancienne chaine old = c->cmd; c->cmd = rtrim(c->cmd, ' '); free(old); //Retour return length + separator; } /* --- Fonctions publiques --- */ int parse_line(CommandTab* ct, char* line){ //Declaration variable int compteur, tmp; //Nettoyage ligne line = trim(mtrim(line, '\n')); //Compte le nombre de commande dans la ligne compteur = nb_commands(line); if(compteur == SHELL_ERR){ return SHELL_ERR; } //Initialisation structure ct->cmd = malloc(sizeof(Command*) * compteur); ct->length = compteur; //Recupération de chaque commande for(int i = 0; i < compteur; i++){ ct->cmd[i] = malloc(sizeof(Command)); tmp = get_command(ct->cmd[i], line); line += tmp; //Si pas dernière commande on trim if(i + 1 < compteur){ line = ltrim(line, ' '); } } //Retour return SHELL_OK; } int parse_command(Command* c){ return 1; } int parse_all_command(CommandTab* ct){ int tmp; for(int i = 0; i < ct->length; i++){ tmp = parse_command(ct->cmd[i]); if(tmp != SHELL_OK){ return SHELL_FAIL; } } return SHELL_OK; } void clean_command(CommandTab* ct){ //Vide le tableau for(int i = 0; i < ct->length; i++){ //Si la commande a été parsée on vide les arguments if(ct->cmd[i]->argc > 0){ ct->cmd[i]->name = NULL; for(int j = 0; j < ct->cmd[i]->argc; j++){ free(ct->cmd[i]->argv[j]); } } //Supprime la ligne de commande free(ct->cmd[i]->cmd); //Supprime la structure free(ct->cmd[i]); } //Met à 0 la taille du tableau ct->length = 0; }