123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * File: parser.c
- * Author: Arthur Brandao
- *
- * Created on 31 octobre 2018
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #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 ou un > avant
- else if(*(line + 1) != '\0' && *(line - 1) != '>'){
- 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;
- c->input = STDIN;
- c->output = STDOUT;
- c->error = STDERR;
- //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){
- extern int errno;
- //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]);
- }
- }
- //Ferme les fichiers ouverts si besoin
- if(ct->cmd[i]->input != STDIN){
- if(close(ct->cmd[i]->input)){
- fprintf(stderr, "Erreur lors de la fermeture du fichier d'input de %s : %s", ct->cmd[i]->cmd, strerror(errno));
- }
- }
- if(ct->cmd[i]->output != STDOUT){
- if(close(ct->cmd[i]->output)){
- fprintf(stderr, "Erreur lors de la fermeture du fichier d'output de %s : %s", ct->cmd[i]->cmd, strerror(errno));
- }
- }
- if(ct->cmd[i]->error != STDERR){
- if(close(ct->cmd[i]->error)){
- fprintf(stderr, "Erreur lors de la fermeture du fichier d'error de %s : %s", ct->cmd[i]->cmd, strerror(errno));
- }
- }
- //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;
- }
|