-
Notifications
You must be signed in to change notification settings - Fork 1
/
analyse_ligne.c
115 lines (96 loc) · 3.69 KB
/
analyse_ligne.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*--------------------------------------------------------------------------
* headers à inclure afin de pouvoir utiliser divers appels systèmes
* -----------------------------------------------------------------------*/
#include <stdio.h> // pour printf and co
#include <stdlib.h> // pour exit
#include <ctype.h> // pour avoir isspace and co
#include <string.h> // pour avoir strcmp and co
/*--------------------------------------------------------------------------
* headers à inclure pour le minishell
* -----------------------------------------------------------------------*/
#include "mini_shell.h"
#include "externes.h"
#include "analyse_ligne.h"
/*--------------------------------------------------------------------------
* Lecture de la ligne de commande
* -----------------------------------------------------------------------*/
void lit_ligne(ligne_analysee_t *ligne_analysee)
{
// lecture de la ligne de commande
// si un fils en arrière-plan est terminé, je dois relancer le fgets
while (! fgets(ligne_analysee->ligne,sizeof(ligne_analysee->ligne)-1,stdin) )
{
// si Ctrl-d est tapé (i.e. EOF), alors on sort du programme
if (feof(stdin))
{
printf("\n");
exit(0);
}
// sinon le NULL provient d'une erreur : fgets interropmu par sigchld
}
}
/*--------------------------------------------------------------------------
* fonction d'analyse de la ligne de commande : extrait la commande numéro num_comm
* -----------------------------------------------------------------------*/
static int decoupe_commande(char **a_debut, ligne_analysee_t *ligne_analysee)
{
int isfg=1;
int i;
// début de la commande numéro num_comm à découper
char *debut = *a_debut;
// on met le mot numéro i dans la case numéro i de commandes[num_comm]
for (i=0; i<NB_MAX_MOTS-1 ;i++) // on laisse la place pour le NULL final
{
/* saute les espaces */
while (*debut && isspace(*debut)) debut++;
/* fin de ligne ? */
if (!*debut)
break;
/* pipe inattendu ? */
if (*debut=='|') {
printf("Erreur : caractère | inattendu\n"); exit(EXIT_FAILURE);
}
/* stocke le début du mot numéro i*/
ligne_analysee->commandes[ligne_analysee->nb_fils][i]=debut;
/* cherche la fin du mot numéro i*/
while (*debut && !isspace(*debut) && *debut != '|') debut++;
/* est-on entre deux arguments? */
if (*debut && isspace(*debut)) {
*debut='\0';
debut++;
while (*debut && isspace(*debut)) debut++;
}
/* est-on entre deux commandes? */
if (*debut == '|') {
*debut='\0';
debut++; i++;
break;
}
}/* fin du parcours des arguments de la commande numéro num_comm*/
/* renvoie où l'on s'est arrêté*/
*a_debut = debut;
/* on n'oublie pas l'élément NULL pour execvp */
ligne_analysee->commandes[ligne_analysee->nb_fils][i] = NULL;
/* pour tester si le dernier mot est &*/
if (i>0 && strcmp("&",ligne_analysee->commandes[ligne_analysee->nb_fils][i-1])==0)
{
ligne_analysee->commandes[ligne_analysee->nb_fils][i-1] = NULL;
isfg=0;
}
return isfg;
}
/*--------------------------------------------------------------------------
* fonction qui extrait chaque commande de la ligne de commande.
* -----------------------------------------------------------------------*/
int extrait_commandes(ligne_analysee_t *ligne_analysee)
{
int isfg=1;
char* debut = ligne_analysee->ligne;
ligne_analysee->nb_fils=0;
while (ligne_analysee->nb_fils<NB_MAX_COMMANDES && *debut)
{
isfg=decoupe_commande(&debut,ligne_analysee);
ligne_analysee->nb_fils++;
}
return isfg;
}