فهرست منبع

:sparkles: Separation des commandes

Loquicom 6 سال پیش
والد
کامیت
bd07d143f9
3فایلهای تغییر یافته به همراه233 افزوده شده و 5 حذف شده
  1. 18 5
      mysh.c
  2. 175 0
      parser.c
  3. 40 0
      parser.h

+ 18 - 5
mysh.c

@@ -7,16 +7,29 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <string.h>
+#include "parser.h"
 
-/*
- * 
- */
-int main(int argc, char* argv[]) {
 
+void test_write(){
     char* a = "azerty\n";
     int tmp = write(1, a, strlen(a));
     printf("%d\n", tmp);
+}
+
+int main(int argc, char* argv[]) {
+
+    CommandTab ct;
+    char str[500];
+    int a;
+    //Recup ligne
+    printf("%s\n", fgets(str, 500, stdin));
+    //Separe les commandes
+    a = parse_line(&ct, str);
+    printf("Result : %d\n\n", a);
+    //Parse les commandes
+    a = parse_all_command(&ct);
+    printf("Result : %d\n\n", a);
+    
     
     return (EXIT_SUCCESS);
 }

+ 175 - 0
parser.c

@@ -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;
+}

+ 40 - 0
parser.h

@@ -0,0 +1,40 @@
+/* 
+ * File:   parser.h
+ * Author: Arthur Brandao
+ *
+ * Created on 31 octobre 2018
+ */
+
+#ifndef PARSER_H
+#define PARSER_H
+
+/* --- Include --- */
+#include "constante.h"
+#include "str.h"
+
+/* --- Structure --- */
+typedef struct{
+    char* cmd; //La commande en string
+    char* name; //Le nom de la commande
+    int argc; //Le nombre d'argument
+    char** argv; //Les arguments
+    int input; //Descripteur de fichier d'entré
+    int output; //Descripteur de fichier de sortie
+    int error; //Descripteur de fihier d'erreur
+    boolean bck; //En fond ou non
+    int next; //Lien avec la prochaine commande
+}Command;
+
+typedef struct{
+    Command** cmd; //Tableau avec toutes les commandes
+    int length; //Taille du tableau
+}CommandTab;
+
+/* --- Fonctions --- */
+int parse_line(CommandTab*, char*);
+int parse_command(Command*);
+int parse_all_command(CommandTab*);
+void clean_command(CommandTab*);
+
+#endif /* PARSER_H */
+