parser.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * File: parser.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 31 octobre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "parser.h"
  10. /* --- Fonctions privées --- */
  11. int nb_commands(char* line){
  12. //Initialisation variable
  13. int compteur = 0;
  14. //Parcours chaine pour chercher séparateur et compter le nombre de commande
  15. while(*line){
  16. //Si un ;
  17. if(*line == ';'){
  18. compteur++;
  19. }
  20. //Si | ou ||
  21. else if(*line == '|'){
  22. //Verif que ce n'est pas le dernier carac
  23. if(*(line + 1) == '\0'){
  24. return SHELL_ERR;
  25. }
  26. //Si un || on avance de 1 en plus
  27. else if(*(line + 1) == '|'){
  28. //Si à la fin de la chaine
  29. if(*(line + 2) == '\0'){
  30. return SHELL_ERR;
  31. }
  32. line++;
  33. }
  34. compteur++;
  35. }
  36. //Si un &&
  37. if(*line == '&'){
  38. //Si celui d'apres est bien un &&
  39. if(*(line + 1) == '&'){
  40. line++;
  41. compteur++;
  42. }
  43. //Sinon il doit y avoir un vide pour etre le & du bck
  44. else if(*(line + 1) != '\0'){
  45. return SHELL_ERR;
  46. }
  47. }
  48. line++;
  49. }
  50. //Ajoute la dernière commande
  51. compteur++;
  52. return compteur;
  53. }
  54. /**
  55. * Recup la 1er commande
  56. * @param c Structure commande à initialiser
  57. * @param line Ligne avec la commande
  58. * @return int Le décallage à effectuer dans line
  59. */
  60. int get_command(Command* c, char* line){
  61. //Declaration variable
  62. char* deb = line, * old;
  63. int length = 0, separator = 0, next = SHELL_NONE;
  64. //Parcours chaine pour chercher un séparateur
  65. while(*line){
  66. //Si un ;
  67. if(*line == ';'){
  68. separator = 1;
  69. break;
  70. }
  71. //Si | ou ||
  72. else if(*line == '|'){
  73. //Si 1 ou 2 |
  74. if(*(line + 1) == '|'){
  75. separator = 2;
  76. next = SHELL_ELSE;
  77. } else {
  78. separator = 1;
  79. next = SHELL_PIPE;
  80. }
  81. break;
  82. }
  83. //Si un &&
  84. if(*line == '&'){
  85. //Si celui d'apres est bien un &&
  86. if(*(line + 1) == '&'){
  87. separator = 2;
  88. next = SHELL_IF;
  89. break;
  90. }
  91. }
  92. length++;
  93. line++;
  94. }
  95. //Verif si c'est la dernière commande
  96. if(!*line){
  97. next = SHELL_END;
  98. }
  99. //Allocation memoire et copie chaine
  100. c->cmd = malloc(sizeof(char) * (length + 1));
  101. strncpy(c->cmd, deb, length);
  102. c->next = next;
  103. c->argc = 0;
  104. //Trim et supprime l'ancienne chaine
  105. old = c->cmd;
  106. c->cmd = rtrim(c->cmd, ' ');
  107. free(old);
  108. //Retour
  109. return length + separator;
  110. }
  111. /* --- Fonctions publiques --- */
  112. int parse_line(CommandTab* ct, char* line){
  113. //Declaration variable
  114. int compteur, tmp;
  115. //Nettoyage ligne
  116. line = trim(mtrim(line, '\n'));
  117. //Compte le nombre de commande dans la ligne
  118. compteur = nb_commands(line);
  119. if(compteur == SHELL_ERR){
  120. return SHELL_ERR;
  121. }
  122. //Initialisation structure
  123. ct->cmd = malloc(sizeof(Command*) * compteur);
  124. ct->length = compteur;
  125. //Recupération de chaque commande
  126. for(int i = 0; i < compteur; i++){
  127. ct->cmd[i] = malloc(sizeof(Command));
  128. tmp = get_command(ct->cmd[i], line);
  129. line += tmp;
  130. //Si pas dernière commande on trim
  131. if(i + 1 < compteur){
  132. line = ltrim(line, ' ');
  133. }
  134. }
  135. //Retour
  136. return SHELL_OK;
  137. }
  138. int parse_command(Command* c){
  139. return 1;
  140. }
  141. int parse_all_command(CommandTab* ct){
  142. int tmp;
  143. for(int i = 0; i < ct->length; i++){
  144. tmp = parse_command(ct->cmd[i]);
  145. if(tmp != SHELL_OK){
  146. return SHELL_FAIL;
  147. }
  148. }
  149. return SHELL_OK;
  150. }
  151. void clean_command(CommandTab* ct){
  152. //Vide le tableau
  153. for(int i = 0; i < ct->length; i++){
  154. //Si la commande a été parsée on vide les arguments
  155. if(ct->cmd[i]->argc > 0){
  156. ct->cmd[i]->name = NULL;
  157. for(int j = 0; j < ct->cmd[i]->argc; j++){
  158. free(ct->cmd[i]->argv[j]);
  159. }
  160. }
  161. //Supprime la ligne de commande
  162. free(ct->cmd[i]->cmd);
  163. //Supprime la structure
  164. free(ct->cmd[i]);
  165. }
  166. //Met à 0 la taille du tableau
  167. ct->length = 0;
  168. }