|
@@ -0,0 +1,175 @@
|
|
|
+/*
|
|
|
+ * File: parser.c
|
|
|
+ * Author: Arthur Brandao
|
|
|
+ *
|
|
|
+ * Created on 31 octobre 2018
|
|
|
+ */
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.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
|
|
|
+ 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;
|
|
|
+}
|