|
@@ -1,197 +1,197 @@
|
|
|
-/*
|
|
|
- * 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;
|
|
|
-}
|
|
|
+/*
|
|
|
+ * 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;
|
|
|
+}
|