/* devoir n1 exercice 1 : menu.h */
char ce_choix(char *tels_autorises, char *tel_libelles[], char *telle_invite);
void affiche_le_menu(char *tel_libelles[], char *telle_invite);
/* devoir n1 exercice 1 : menu.c */
#include <menu.h>
#include <stdio.h>
void affiche_le_menu(char *tels_libelles[], char *telle_invite){
	int l_indice = 0;
	while(tels_libelles[l_indice]){
		printf("%s", tels_libelles[l_indice]);
		l_indice++;
		}
	printf("%s",telle_invite);
	}	
char ce_choix(char *tels_autorises, char *tel_libelles[], char *telle_invite){
	int la_place, l_indice;
	char le_choix;
	affiche_le_menu(tel_libelles, telle_invite);
	fflush(stdin);
	scanf("%c", &le_choix);
	fflush(stdin);
	for(la_place = l_indice = 0; !la_place && tels_autorises[l_indice]; l_indice++){
		if(le_choix == tels_autorises[l_indice]){
			la_place++;
			}
		}
	if(la_place)
		return le_choix;
		else return 0;
	}
/* devoir n1 exercice 1 : pp.h */
#define MAX_ELEMENTS 20
#define MAX_VALEUR 100
extern int le_tableau[];
/* devoir n1 exercice 1 : pp.c */
#include <pp.h>
#include <menu.h>
#include <recherches.h>
#include <moyenne.h>
#include <tri.h>
#include <stdio.h>
int le_tableau[MAX_ELEMENTS];
static char *les_libelles[] = { 	
	"\n\tMENU\n\n",
	"\t1 - Changer les valeurs du tableau.\n",
	"\t2 - Rechercher le maximum\n",
	"\t3 - Rechercher les 2 maximas\n",
	"\t4 - Rechercher le maximum et le minimum\n",
	"\t5 - Rechercher le minimum\n"
	"\t6 - Rechercher les 2 minimas.\n",
	"\t7 - Calculer la moyenne du tableau.\n",
	"\t8 - Trier le tableau\n",
	"\t0 - Terminer\n\n",
	NULL
	};
static char *les_autorises = "123456780";
static char *l_invite = "\tVotre choix :";
void main(void){
	int run = 1;
	remplis_le_tableau();
	while(run){
		switch(ce_choix(les_autorises, les_libelles, l_invite)){
			case '1':remplis_le_tableau();
				break;
			case '2':recherches(LE_MAX);
				break;
			case '3':recherches(LE_MAX_MAX);
				break;
			case '4':recherches(LE_MIN + LE_MAX);
				break;
			case '5':recherches(LE_MIN);
				break;
			case '6':recherches(LE_MIN_MIN);
				break;
			case '7':calcule_la_moyenne();
				break;
			case '8':tri();
				break;
			case '0':run = 0;
				break;
			}
		}
	} 
/* devoir n1 exercice 2 : pp.h */
#define MAX 30
#define ELEMENTS 20
typedef struct {
	int (*fonction)(int *pt_a, int *pt_b);
	char *message;
	} lien;
int compare(int *pt_a, int *pt_b);
int compare_unites(int *pt_a, int *pt_b);
int compare_farfelu(int *pt_a, int *pt_b);
/* devoir n1 exercice 2 : pp.c */
#include <pp.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
/* tri : ordre croissant */
int compare(int *pt_a, int *pt_b){
	if(*pt_a > *pt_b) return 1;
	if(*pt_a < *pt_b) return -1;
	return 0;
	}
/* tri : ordre croissant du chiffre des unites */
int compare_unites(int *pt_a, int *pt_b){
	int a = *pt_a, b = *pt_b;
	if(a < 0) a = -a;
	else while(a > 9) a -= 10;
	if(b < 0) b = -b;
	else while(b > 9) b -= 10;
	return(compare(&a, &b)); 
	}
/* tri : tout nombre positif doit apparaitre avant tout nombre negatif 
 *       les nombres positifs sont tries par ordre croissant
 *       et les nombres negatifs sont tries par ordre decroissant 
 */
int compare_farfelu(int *pt_a, int *pt_b){
	int a = *pt_a, b = *pt_b;
	if(a < 0) a = (-a) + MAX;
	if(b < 0) b = (-b) + MAX;
	return(compare(&a, &b)); 
	}
/* main */
signed int le_tableau[ELEMENTS];
lien compare_f[] = { 
	{compare, "Tri croissant:"},
	{compare_unites, "Tri croissant du chiffre des unites:"},
	{compare_farfelu, "Tri farfelu:"},
	NULL
	};
void main(void){
	int l_index, loop = 0;
	time_t t;
	(void)time(&t);
	(void)srand((unsigned int)t);
	printf("\tContenu du tableau:\n\t");
	for(l_index = 0; l_index < ELEMENTS; l_index++){
		le_tableau[l_index]= (rand() % (MAX + 10)) - 9;
		printf("%d ", le_tableau[l_index]);
		}
	printf("\n");
	while(compare_f[loop].fonction){
		qsort(le_tableau, ELEMENTS, sizeof(int), compare_f[loop].fonction);
		printf("\t%s\n\t", compare_f[loop].message);
		for(l_index = 0; l_index < ELEMENTS; l_index++){
			printf("%d ", le_tableau[l_index]);
			}
		printf("\n");
		loop++;
		}
	}
/* exemples d'executions
[root@localhost /root]# cd /usr/src/cours/dev1ex2/
[root@localhost /usr/src/cours/dev1ex2]# gcc -o/usr/bin/pp -I./ pp.c
[root@localhost /usr/src/cours/dev1ex2]# pp
        Contenu du tableau:
        -2 -4 17 -1 5 27 -9 19 0 1 9 13 9 2 7 24 2 2 -9 -7
        Tri croissant:
        -9 -9 -7 -4 -2 -1 0 1 2 2 2 5 7 9 9 13 17 19 24 27
        Tri croissant du chiffre des unites:
        0 -1 1 -2 2 2 2 13 -4 24 5 -7 7 17 27 -9 -9 9 9 19
        Tri farfelu:
        0 1 2 2 2 5 7 9 9 13 17 19 24 27 -1 -2 -4 -7 -9 -9
[root@localhost /root]# pp
        Contenu du tableau:
        20 7 12 19 10 0 20 14 6 2 30 -2 20 30 -2 29 21 16 -9 7
        Tri croissant:
        -9 -2 -2 0 2 6 7 7 10 12 14 16 19 20 20 20 21 29 30 30
        Tri croissant du chiffre des unites:
        0 10 20 20 20 30 30 21 -2 -2 2 12 14 6 16 7 7 -9 19 29
        Tri farfelu:
        0 2 6 7 7 10 12 14 16 19 20 20 20 21 29 30 30 -2 -2 -9
[root@localhost /root]#
*/
/* langage algorithmique
procedure compare(pt_a : pointeur d'entier, pt_b : pointeur d'entier)
debut
	si *pt_a et strictement superieur a *pt_b
		alors retourne 1;
	si *pt_b et strictement superieur a *pt_b
		alors retourne -1;
	retourne 0;
fin
procedure compare_unites(pt_a : pointeur d'entier, pt_b : pointeur d'entier)
variable a, b : entier;
debut
	a = *pt_a;
	b = *pt_b;
	si a est strictement inferieur a 0
		alors a = -a;
	sinon
	tant que a et strictement superieur a 9
		alors a -= 10;
	fin de si
	si b est strictement inferieur a 0
		alors b = -b;
	sinon
	tant que b et strictement superieur a 9
		alors b -= 10;
	fin de si
	retourne compare(&a, &b);
fin
definition MAX 30
procedure compare_farfelu(pt_a : pointeur d'entier, pt_b : pointeur d'entier)
variable a, b : entier;
debut
	a = *pt_a;
	b = *pt_b;
	si a est strictement inferieur a 0
		alors a = (-a) + MAX;
	si b est strictement inferieur a 0
		alors b = (-b) + MAX;
	retourne compare(&a, &b);
fin
definition ELEMENTS 20
structure compare_f;
programme pricipal main()
variable l_index, loop, t : entier;
debut
	time(&t);
	srand(t);
	affiche "Contenu du tableau";
	pour l_index = 0 jusqu'a l_index strictement inferieur  ELEMENTS faire
		le_tableau[l_index] = un nombre aleatoire compris entre -9 et MAX;
		affiche le_tableau[l_index];
	fin de pour
	tant que compare_f[loop].fonction faire
		qsort(le_tableau, ELEMENTS, sizeof(entier), compare_f[loop].fonction);
		affiche compare_f[loop].message;
		pour l_index = 0 jusqu'a l_index strictement inferieur  ELEMENTS faire
			affiche le_tableau[l_index];
		fin de pour
	fin de tant que
fin
*/
/* devoir n1 exercice 3 : pp.h */
void echangep(char *pt_a, char *pt_b);
/* devoir n1 exercice 3 : pp.c */
#include <pp.h>
#include <stdio.h>
void echangep(char *pt_a, char *pt_b){
	char tmp;
	tmp =  *pt_a;
	*pt_a = *pt_b;
	*pt_b = tmp;
	}
void main(void){
	int int_a = 7, int_b = 1256;
	double double_a = 1256.2, double_b = 2512.4;
	char char_a[] = "deux", char_b[] = "dix";
	char *pt_a, *pt_b;
	
	pt_a = (char *)&int_a;
	pt_b = (char *)&double_a;
	printf("\n\tAvant exhangep\ta = %8d\t b = %5.3f\n", *((int *)pt_a), *((double *)pt_b) );
	echangep((char *)&pt_a, (char *)&pt_b);
	printf("\tApres exhangep\ta = %5.3f\t b = %8d\n\n", *((double *)pt_a), *((int *)pt_b) );
	pt_a = (char *)&int_b;
	pt_b = (char *)&char_a;
	printf("\tAvant exhangep\ta = %8d\t b = %8s\n", *((int *)pt_a), (char *)pt_b );
	echangep((char *)&pt_a, (char *)&pt_b);
	printf("\tApres exhangep\ta = %8s\t b = %8d\n\n", (char *)pt_a, *((int *)pt_b) );
	pt_a = (char *)&char_b;
	pt_b = (char *)&double_b;
	printf("\tAvant exhangep\ta = %8s\t b = %5.3f\n", (char *)pt_a, *((double *)pt_b) );
	echangep((char *)&pt_a, (char *)&pt_b);
	printf("\tApres exhangep\ta = %5.3f\t b = %8s\n\n", *((double *)pt_a), (char *)pt_b );
	}  
/* exemple d'execution
[root@localhost /root]# gcc -o/bin/ex3 /usr/src/cours/dev1ex3/dev1ex3.c
[root@localhost /root]# ex3
        Avant exhangep  a =        7     b = 1256.200
        Apres exhangep  a = 1256.200     b =        7
        Avant exhangep  a =     1256     b =     deux
        Apres exhangep  a =     deux     b =     1256
        Avant exhangep  a =      dix     b = 2512.400
        Apres exhangep  a = 2512.400     b =      dix
[root@localhost /root]#     
*/ 
/* langage algorithmique 
procedure echangep(pt_a : pointeur de caractere, pt_b : pointeur de caractere)
variable tmp : caractere;
debut
	tmp = *pt_a;
	*pt_a = *pt_b;
	*pt_b = tmp;
fin
programme principal main()
variable int_a, int_b : entier;
variable double_a, double_b : double;
variable char_a[], char_b[] : tableau de caracteres;
variable *pt_a, *pt_b : pointeur de caractere;
debut
	pt_a = (char *)&int_a;
	pt_b = (char *)&double_a;
	affiche entier pointe par pt_a et double pointe par pt_b;
	echangep ((char *)&pt_a, (char *)&pt_b);
	affiche double pointe par pt_a et entier pointe par pt_b;
	pt_a = (char *)&int_b;
	pt_b = (char *)&char_a;
	affiche entier pointe par pt_a et tableau pointe par pt_b;
	echangep((char *)&pt_a, (char *)&pt_b);
	affiche tableau pointe par pt_a et entier pointe par pt_b;
	pt_a = (char *)&char_b;
	pt_b = (char *)&double_b;
	affiche tableau pointe par pt_a et double pointe par pt_b;
	echangep((char *)&pt_a, (char *)&pt_b);
	affiche double pointe par pt_a et tableau pointe par pt_b;
fin
*/
/* devoir n1 exercice 4a : pile_t.h */
#define MAX 5
typedef struct {
	int sommet;
	int elements[MAX];
	} une_pile;
int depile(une_pile *la_pile);
int empile(une_pile *la_pile, int val);
void vide(une_pile *la_pile);
/* devoir n1 exercice 4 : depile_t.c */
#include <pile_t.h>
int depile(une_pile *la_pile){
	if(la_pile->sommet){
		int retval = la_pile->elements[la_pile->sommet - 1];
		la_pile->sommet -= 1;
		return(retval);
		}
	else return -1;
	}
/* langage algorithmique 
procedure depile(la_pile : pointeur une_pile)
debut
	si la_pile->sommet non nul
		variable retval = la_pile->element[la_pile->sommet - 1];
		decremente la_pile->sommet;
		retourne retval
	fin de si
	sinon retourne -1;
fin
*/
/* devoir n1 exercice 4 : empile_t.c */
#include <pile_t.h>
int empile(une_pile *la_pile, int val){
	if(val >= 0){
		if(la_pile->sommet < MAX ){
			la_pile->elements[la_pile->sommet] = val;
			la_pile->sommet += 1;
			return 0;
			}
		else return -1;
		}
	else return -2;
	}
/* langage algorithmique 
declaration MAX 5
procedure empile(la_pile : pointeur une_pile, val : entier)
debut
	si val est superieur ou egal a 0
		si la_pile->sommet est strictement inferieur a MAX
			la_pile->element[la_pile->sommet ] = val;
			incremente la_pile->sommet;
			retourne 0
		fin de si
		sinon retourne -1;
	fin de si
	sinon retourne -2;
fin
*/
/* devoir n1 exercice 4 : vide_t.c */
#include <pile_t.h>
void vide(une_pile *la_pile){
	la_pile->sommet = 0;
	}
/* langage algorithmique 
procedure vide(une_pile : pointeur la_pile)
debut
	la_pile->sommet = 0;
fin
*/
/* devoir n1 exercice 4 : pp_t.c */
#include <pile_t.h>
#include <stdio.h>
static char *les_libelles[] = { 
	"\n\tMENU\n\n",
	"\t1 - Empiler un entier positif\n",
	"\t2 - Depiler une valeur\n",
	"\t3 - Vider la pile\n",
	"\t0 - Quiter\n\n",
	NULL
	};
static char *les_autorises = "1230";
static char *l_invite = "\tVotre choix :";
void affiche_le_menu( char *tels_libelles[], char *telle_invite ){
	register int l_indice = 0;
	while(tels_libelles[l_indice]){
		printf("%s", tels_libelles[l_indice]);
		l_indice++;
		}
	printf("%s",telle_invite);
	}
char ce_choix( char *tels_autorises, char *tel_libelles[], char *telle_invite ){
	register int la_place, l_indice;
	char le_choix;
	affiche_le_menu(tel_libelles, telle_invite);
	fflush(stdin);
	scanf("%c", &le_choix);
	fflush(stdin);
	for(la_place = l_indice = 0; !la_place && tels_autorises[l_indice]; l_indice++){
		if(le_choix == tels_autorises[l_indice]){
			la_place++;
			}
		}
	if(la_place)
		return le_choix;
		else return 0;
	}
int ce_nombre(){
	int le_nombre;
	printf("\tValeur a empiler :");
	scanf("%d", &le_nombre);
	return le_nombre;
	}
void main(void){
	int val = 0, run = 1;
	une_pile ma_pile = {0, 0};
	while(run){
		switch(ce_choix(les_autorises, les_libelles, l_invite)){
			case '1':
				switch( empile(&ma_pile, ce_nombre())){
					case 0:
						printf("\tOperation reussie.\n");
						break;
					case -1:
						printf("\tLa pile est pleine, entier non empile.\n");
						break;
					case -2:
						printf("\tCe nombre n'est pas strictement positif.\n");
						break;
					}
				break;
			case '2':
				val = depile(&ma_pile);
				val < 0 ? printf("\tLa pile est vide.\n") : printf("\tValeur depilee :%d\n", val);
				break;
			case '3':
				vide(&ma_pile);
				printf("\tPile videe.\n");
				break;
			case '0':
				printf("\tFin de traitement.\n");
				run = 0;
				break;
			}
		}
	}
/* exemple d'execution
[root@localhost /root]# cd /usr/src/cours/dev1ex4a/
[root@localhost /usr/src/cours/dev1ex4a/]# sh projet_t.prj
[root@localhost /usr/src/cours/dev1ex4a/]# pp_t
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :1
        Valeur a empiler :20
        Operation reussie.
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :1
        Valeur a empiler :21
        Operation reussie.
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :2
        Valeur depilee :21
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :3
        La pile a ete videe.
                
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :2
        La pile est vide.
               
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :0
        Fin de traitement.                                              
[root@localhost /root]#
*/
/* langage algorithmique 
procedure affiche_le_menu(tels_libelles : pointeur tableau, telle_invite : pointeur tableau)
debut
	tant que tels_libelles non nul
		affiche tels_libelles;
	fin de tant que
	affiche telle_invite;
fin
procedure ce_choix() : caractere;
debut
	affiche_le_menu();
	saisir le_choix;
	si le_choix est autorise alors
		retourne le_choix
	fin de si
	sinon retourne 0;
fin
procedure principale main()
variable *ma_pile : pointeur une_pile;
debut
	tant que
		suivant la valeur de ce_choix() faire
			'1':suivant la valeur de empile(&ma_pile, ce_nombre())
				0: affiche "Operation reussie";
				-1: affiche "La pile est pleine, entier non empile";
				-2: affiche "Ce nombre n'est pas strictement positif";
				fin de suivant
			'2':depile(&ma_pile) < 0 alors affiche "La pile est vide" sinon affiche la valeur depilee
			'3':vide(&ma_pile);
			    affiche "Pile videe";
			'0':quitte;
		fin de suivant
	fin de tant que
fin
*/
#!/bin/sh
# devoir n1 exercice 4 : projet_t.prj
gcc -o/usr/bin/pp_t -I./ ./depile_t.c ./empile_t.c ./pp_t.c ./vide_t.c
/* devoir n1 exercice 4b : pile_l.h */
#define MAX 5
typedef struct pile {
	int element;
	struct pile *suivant;
	} une_pile;
typedef struct {
	une_pile *debut;
	} tete_de_pile;
int depile(tete_de_pile *le_debut);
int empile(tete_de_pile *le_debut, int val);
void vide(tete_de_pile *le_debut);
/* devoir n1 exercice 4b : depile_l.c */
#include <pile_l.h>
int depile(tete_de_pile *tdp){
	int retval;
	une_pile *p = (une_pile *)tdp->debut;
	if(p){
		retval = p->element;
		tdp->debut = p->suivant;
		free(p);
		return(retval);
		}
	else return -1;
	}
/* langage algorithmique 
procedure depile(tdp : pointeur tete_de_pile)
variable retval : entier, *p : pointeur une_pile;
debut
	p = tdp->debut;
	si p non nul
		retval = p->element;
		tdp->debut = p->suivant;
		libere p;
		retourne retval;
	fin de si
	sinon retourne -1
fin
*/
/* devoir n1 exercice 4b : empile_l.c */
#include <pile_l.h>
int empile(tete_de_pile *tdp, int val){
	une_pile *p;
	if(val >= 0){
		if(!(p = (une_pile *) malloc(sizeof(une_pile)))){
			return -1;
			}
		p->element = val;
		p->suivant = tdp->debut;
		tdp->debut = p;
		return 0;
		}
	return -2;
	}
/* langage algorithmique 
procedure empile(tdp : pointeur tete_de_pile, val : entier)
debut
	si val est superieur ou egal a 0
		si aloue p = nul
			retourne -1;
		fin de si
		p->element = val;
		p->suivant = tdp->debut;
		tdp->debut = p;
		retourne 0;
	fin de si
	sinon retourne -2;
fin
*/
/* devoir n1 exercice 4b : vide_l.c */
#include <pile_l.h>
void vide(tete_de_pile *la_tdp){
	while(depile(la_tdp)!=-1);
	}
/* langage algorithmique 
procedure vide(la_tdp : pointeur tete_de_pile)
debut
	tant que depile(la_tdp) different de -1;
fin
*/
/* devoir n1 exercice 4b : pp_l.c */
#include <pile_l.h>
#include <stdio.h>
static char *les_libelles[] = { 
	"\n\tMENU\n\n",
	"\t1 - Empiler un entier positif\n",
	"\t2 - Depiler une valeur\n",
	"\t3 - Vider la pile\n",
	"\t0 - Quiter\n\n",
	NULL
	};
static char *les_autorises = "1230";
static char *l_invite = "\tVotre choix :";
void affiche_le_menu( char *tels_libelles[], char *telle_invite ){
	int l_indice = 0;
	while(tels_libelles[l_indice]){
		printf("%s", tels_libelles[l_indice]);
		l_indice++;
		}
	printf("%s",telle_invite);
	}
char ce_choix( char *tels_autorises, char *tel_libelles[], char *telle_invite ){
	int la_place, l_indice;
	char le_choix;
	affiche_le_menu(tel_libelles, telle_invite);
	fflush(stdin);
	scanf("%c", &le_choix);
	fflush(stdin);
	for(la_place = l_indice = 0; !la_place && tels_autorises[l_indice]; l_indice++){ 
		if(le_choix == tels_autorises[l_indice]){
			la_place++;
			}
		}
	if(la_place)
		return le_choix;
		else return 0;
	}
int ce_nombre(){
	int le_nombre;
	printf("\tValeur a empiler :");
	scanf("%d", &le_nombre);
	return le_nombre;
	}
void main(void){
	int val = 0, run = 1;
	tete_de_pile ma_tdp = { NULL };
	while(run){
		switch(ce_choix(les_autorises, les_libelles, l_invite)){
			case '1':
				switch(empile(&ma_tdp, ce_nombre())){
					case 0:
						printf("\tOperation reussie.\n");
						break;
					case -1:
						printf("\tLa pile (memoire) est pleine, entier non empile.\n");
						break;
					case -2:
						printf("\tCe nombre n'est pas strictement positif.\n");
						break;
					}
				break;
			case '2':
				val = depile(&ma_tdp);
				val < 0 ? printf("\tLa pile est vide.\n") : printf("\tValeur depilee :%d.\n", val);
				break;
			case '3':
				vide(&ma_tdp);
				printf("\tPile videe.\n");
				break;
			case '0':
				printf("\tFin de traitement.\n");
				run = 0;
				break;
			}
		}
	}
/* exemple d'execution
[root@localhost /root]# cd /usr/src/cours/dev1ex4b/
[root@localhost /usr/src/cours/dev1ex4b/]# sh projet_l.prj
[root@localhost /usr/src/cours/dev1ex4b/]# pp_l
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :1
        Valeur a empiler :20
        Operation reussie.
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :1
        Valeur a empiler :21
        Operation reussie.
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :2
        Valeur depilee :21
        
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :3
        La pile a ete videe.
                
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :2
        La pile est vide.
               
        MENU
        1 - Empiler un entier positif
        2 - Depiler une valeur
        3 - Vider la pile
        0 - Quiter
        Votre choix :0
        Fin de traitement.                                              
[root@localhost /root]#
*/
/* langage algorithmique 
procedure affiche_le_menu(tels_libelles : pointeur tableau, telle_invite : pointeur tableau)
debut
	tant que tels_libelles non nul
		affiche tels_libelles;
	fin de tant que
	affiche telle_invite;
fin
procedure ce_choix() : caractere;
debut
	affiche_le_menu();
	saisir le_choix;
	si le_choix est autorise alors
		retourne le_choix
	fin de si
	sinon retourne 0;
fin
procedure principale main()
variable *ma_tdp : pointeur tete_de_pile;
debut
	tant que
		suivant la valeur de ce_choix() faire
			'1':suivant la valeur de empile(&ma_tdp, ce_nombre())
				0: affiche "Operation reussie";
				-1: affiche "La pile est pleine, entier non empile";
				-2: affiche "Ce nombre n'est pas strictement positif";
				fin de suivant
			'2':depile(&ma_tdp) < 0 alors affiche "La pile est vide" sinon affiche la valeur depilee
			'3':vide(&ma_tdp);
			    affiche "Pile videe";
			'0':quitte;
		fin de suivant
	fin de tant que
fin
*/
#!/bin/sh
# devoir n1 exercice 4 : projet_l.prj
gcc -o/usr/bin/pp_l -I./ ./pp_l.c ./depile_l.c ./empile_l.c ./vide_l.c

 

/* devoir n2 exercice 1 : pp.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
	
pid_t le_pid_A, le_pid_B;
int compteur = 1;
void traite_le_SIGUSR1_A(){
	}
	
void traite_le_SIGUSR1_B(){
	printf("Message recu !\n");
	}
void traite_le_A(){
	int i;
	signal( SIGUSR1, traite_le_SIGUSR1_A );
	for( i = 0; i < 5; i++ ) printf("A\n");
	kill( le_pid_B, SIGUSR1 );
	pause();
	traite_le_A();
	}
void traite_le_B(){
	signal( SIGUSR1, traite_le_SIGUSR1_B );
	pause();
	compteur++;
	if( compteur > 5 ){
		kill( le_pid_A, SIGKILL );
		kill( le_pid_B, SIGKILL );
		}
	else kill( le_pid_A, SIGUSR1 );
	traite_le_B();
	}
main( ){
	le_pid_A = getpid();
	if( (le_pid_B = fork()) == -1 ){
		printf("fork() non possible\n");
		exit();
		}
	sleep(1);
	if( le_pid_B == 0 ) traite_le_B();
	else traite_le_A();
	}
/* langage algorithmique 
procedure traite_le_SIGUSR1_A()
debut
fin
procedure traite_le_SIGUSR1_B()
debut
	affiche "Message recu !"
fin
procedure traite_le_A()
variable i : entier
debut
	si reception du signal SIGUSR1 alors saute  traite_le_SIGUSR1_A()
	pour i = 0 jusqu'a i strictement inferieur a 5 affiche "A"
	emet au processus B le signal SIGUSR1
	attend un message
	traite_le_A()
fin
procedure traite_le_B()
debut
	si reception du signal SIGUSR1 alors saute  traite_le_SIGUSR1_B()
	attend un message
	incremente la variable compteur
	si la variable compteur est superieure a 5 alors 
		emet au processus A le signal SIGKILL
		emet au processus B le signal SIGKILL
		sinon emet au processus A le signal SIGUSR1
	fin de si
	
	traite_le_B()
fin
procedure principale main()
debut
	le_pid_A = getpid()
	si ( le_pid_B = fork() ) == -1 
		affiche "fork() non possible"
	fin de si
	attend la mise en place de la fourche
	si le_pid_B == 0 
		traite_le_B()
		sinon traite_le_A()
	fin de si
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pp /usr/src/cours/devoir2/dev2ex1/pp.c
[root@localhost /root]# pp
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
Killed
[root@localhost /root]#  
*/
/* devoir n2 exercice 2 petit 1: envoie.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
char *nbr_tty[16] = {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
void sortie(){
	printf("10 secondes coulees, sortie.\n");
	exit();
	}
main( ){
	int i, fd_tty;
	char dev_tty[11];
	signal( SIGALRM, sortie );
	alarm( 10 );
	for( i=0; i <= 15; i++ ){
		strcpy( dev_tty, "\0" );
		strcat( dev_tty, "/dev/tty" );
		strcat( dev_tty, nbr_tty[i] );
		if( fd_tty = open( dev_tty, O_WRONLY ) ){
			write( fd_tty, "coucou, le monde\n", 17 );	
			close( fd_tty );
			}
		}
	}
/* langage algorithmique 
procedure sortie()
debut
	affiche "10 secondes ecoulees, sortie."
	sortie
fin
procedure principale main()
variable i : type entier
variable fdd_tty : type entier
variable dev_tty[11] : type tableau 11 caracteres
debut
	si reception du signal SIGALRM alors saute  sortie()
	alarm()
	pour i = 0 jusqu'a i strictement inferieur ou egal a 16 
		copie "\0" dans dev_tty
		concatene "/dev/tty" dans dev_tty
		concatene nbr_tty[i] dans dev_tty
		si ouvre le fichier fd_tty du nom inscrit dans le tableau dev_tty en mode lecture seule
			ecrit "coucou, le monde\n" dans le fichier fd_tty	
			ferme le fichier fd_tty 
		fin de si
	fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/envoie /usr/src/cours/devoir2/dev2ex2/1/envoie.c
[root@localhost /root]# envoie
coucou, le monde
[root@localhost /root]#
(idem sur les 15 autres terminaux)
*/
/* devoir n2 exercice 2 petit 2: pilote.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define SECONDES 63
void fourche(){	
	pid_t le_pid = fork();
	if( le_pid == 0 ){
		execlp( "envoie", NULL );
		printf("erreur dans exec.\n");
		kill( getppid(), SIGKILL );
		kill( getpid(), SIGKILL );
		}
	else 
	if ( le_pid == -1 ){
		printf("fork() non possible.\n");
		exit();
		}
	}
main(){
	signal( SIGALRM, fourche );
	fourche();
	for(;;){
		alarm( SECONDES );
		pause();
		}
	}
/* langage algorithmique 
definition SECONDE 63
procedure fourche()
variable le_pid : pid_t
debut
	le_pid = fork()
	si le_pid == 0
		execlp( "envoie", NULL )
		affiche "erreur dans exec."
		emet au processus getppid() le signal SIGKILL
		emet au processus getpid() le signal SIGKILL
	sinon si le_pid == -1
		affiche "fork() non possible."
		sortie
	fin de si
fin
procedure main()
debut
	si reception du signal SIGALRM alors saute  fourche
	fourche()
	pour jusqu'a l'infini
		alarm( SECONDES )
		attend un message
	fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pilote /usr/src/cours/devoir2/dev2ex2/2/pilote.c
[root@localhost /root]# pilote
coucou, le monde
coucou, le monde <-- 63 secondes
coucou, le monde <-- 63 secondes
'^c'
[root@localhost /root]#
(idem sur les 15 autres terminaux)
*/
/* devoir n2 exercice 2 petit 3: pilote.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define SECONDES 63
char *cmd_line;
void fourche(){	
	pid_t le_pid = fork();
	if( le_pid == 0 ){
		execlp( cmd_line, cmd_line, NULL );
		printf("erreur dans exec.\n");
		kill( getppid(), SIGKILL );
		kill( getpid(), SIGKILL );
		}
	else 
	if ( le_pid == -1 ){
		printf( "fork() non possible\n" );
		exit();
		}
	}
main( int argc, char *argv[] ){
	if( argc < 2 ){ printf("Pas assez de parametres.\n"); exit(); }
	if( argc > 2 ){ printf("Trop de parametres.\n"); exit(); }
	cmd_line = (char *) malloc( strlen( argv[1] ));
	strcpy( cmd_line, argv[1] );
	signal( SIGALRM, fourche );
	fourche();
	for(;;){
		alarm( SECONDES );
		pause();
		}
	}
/* langage algorithmique 
definition SECONDES 63
variable cmd_line : pointeur de caracteres
procedure fourche()
variable le_pid : pid_t
debut
	le_pid = fork()
	si le_pid == 0
		execlp( cmd_line, cmd_line, NULL )
		affiche "erreur dans exec."
		emet au processus getppid() le signal SIGKILL
		emet au processus getpid() le signal SIGKILL
	sinon si le_pid == -1
		affiche "fork() non possible."
		sortie
	fin de si
fin
procedure main( variable argc : entier, variable argv : pointeur tableau de cararcteres )
debut
	si argc strictement inferieur a 2 
		affiche "Pas assez de parametres."
		sortie
	fin de si
	si argc strictement superieur a 2 
		affiche "Trop de parametres."
		sortie
	fin de si
	cmd_line = (char *) malloc( strlen( argv[1] ))
	strcpy( cmd_line, argv[1] )
	si reception du signal SIGALRM alors saute  fourche
	fourche()
	pour jusqu'a l'infini
		alarm( SECONDES )
		attend un message
	fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pilote /usr/src/cours/devoir2/dev2ex2/3/pilote.c
[root@localhost /root]# pilote ls
Desktop        Sans titre     autosave       config.log     nsmail
Makefile       Xrootenv.0     config.cache   config.status
Desktop        Sans titre     autosave       config.log     nsmail
Makefile       Xrootenv.0     config.cache   config.status <-- 63 secondes
Desktop        Sans titre     autosave       config.log     nsmail
Makefile       Xrootenv.0     config.cache   config.status <-- 63 secondes
'^c'
[root@localhost /root]#
*/
/* devoir n2 exercice 2 projet: pp.c */
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#define ENTREE 1
#define SORTIE 0
#define NL 10
int toggle = 0;
int le_tube[2];
FILE *la_sortie, *l_entree;
pid_t le_pid_A, le_pid_B, le_pid_C;
void traite_le_SUGUSR1_A(){
	printf("Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)\n");
	toggle = !toggle;
	}
void traite_le_SUGUSR2_A(){
	if ( toggle == 0 ){
		printf("Le pere A : signal recu de B : SIGUSR2\n");
		toggle = !toggle; 
		printf("Le pere A : envoie au fils C : SIGUSR2\n");
		kill( le_pid_C, SIGUSR2 );
		}
	if ( toggle == 1 ){	
		printf("Le pere A : signal recu de C : SIGUSR2\n");
		printf("Le pere A : Fin du fils B.\n");
		kill( le_pid_B, SIGKILL );
		printf("Le pere A : Fin du fils C.\n");
		kill( le_pid_C, SIGKILL );
		printf("Le pere A : Fin de moi !\n");
		kill( le_pid_A, SIGKILL );
		}
	pause();
	}
void traite_le_SUGUSR1_B(){
	/* ne marche pas sur mon systeme ?
	le_buf = realloc( le_buf, ++i ); 
	*/
	int i = 0, le_car;
	char le_buf[100]; 
	printf("\tLe fils B : message a envoyer :"); 
	while( (le_car = fgetc( stdin )) != NL && i <= 99 ){
		if( le_car == EOF ){
			close( le_tube[ENTREE] );
			printf("\n\tLe fils B : envoie au pere A : SIGUSR2\n");
			kill( le_pid_A, SIGUSR2 );
			pause();
			}
		fputc( le_car, l_entree );
		i++;
		}
	printf("\tLe fils B : ecriture et envoie du message\n"); 
	fputc( NL, l_entree );
	fflush( l_entree );
	}
void traite_le_SUGUSR1_C(){
	int le_car = 0, premier = 0;
	printf("\t\tLe fils C : signal recu : SIGUSR1\n");
	printf("\t\tLe fils C : message recu : ");
	while( (le_car = fgetc( la_sortie )) != NL ){
		if( le_car >= 97 && le_car <= 122 ) le_car = le_car - 32;	
		printf("%c", le_car);
		premier ++;
		}
	if( premier == 0 ) printf("PAS DE MESSAGE");
	printf("\n");
	}
void traite_le_SUGUSR2_C(){
	printf("\t\tLe fils C : signal recu : SIGUSR2\n");
	close( le_tube[SORTIE] );
	printf("\t\tLe fils C : envoie au pere A : SIGUSR2\n");
	kill( le_pid_A, SIGUSR2 );
	pause();
	}
void traite_le_A(){
	signal( SIGUSR1, traite_le_SUGUSR1_A );
	signal( SIGUSR2, traite_le_SUGUSR2_A );
	if ( toggle == 0 ){
		printf("Le pere A : signal envoye : SIGUSR1 (autorisation tache B)\n");
		kill( le_pid_B, SIGUSR1 );
		}
	else if ( toggle == 1 ){
		printf("Le pere A : signal envoye : SIGUSR1 (autorisation tache C)\n");
		kill( le_pid_C, SIGUSR1 );
		}
	pause();
	traite_le_A();
	}
void traite_le_B(){
	signal( SIGUSR1, traite_le_SUGUSR1_B );
	pause();
	printf("\tLe fils B : envoie au pere A de SIGUSR1\n"); 
	kill( le_pid_A, SIGUSR1 );
	traite_le_B();
	}
void traite_le_C(){
	signal( SIGUSR1, traite_le_SUGUSR1_C );
	signal( SIGUSR2, traite_le_SUGUSR2_C );
	pause();
	printf("\t\tLe fils C : envoie au pere A de SIGUSR1\n"); 
	kill( le_pid_A, SIGUSR1 );
	traite_le_C();
	}
main(){
	if( pipe( le_tube ) == -1 ){
		printf( "Erreur dans pipe();\n" );
		exit();
		}
	le_pid_A = getpid();
	if( ( le_pid_B = fork() ) == -1 ){
		printf( "Erreur dans fork();\n" );
		exit();
		}
	else if( le_pid_B == 0 ){
		printf("\tDebut du fils B\n");
		close( le_tube[SORTIE] );
		if(!( l_entree = fdopen( le_tube[ENTREE], "w" ))){
			printf("Erreur dans fdopen();\n");
			kill( le_pid_A, SIGKILL );
			kill( le_pid_B, SIGKILL );
			}
		printf("\tFils B : debut de l'attente\n");
 		traite_le_B();
		}
	sleep(1);
	if( ( le_pid_C = fork() ) == -1 ){
		printf("Erreur dans fork();\n");
		kill( le_pid_B, SIGKILL );
		exit();
		}
	else if( le_pid_C == 0 ){
		printf("\t\tDebut du fils C\n");
		close( le_tube[ENTREE] );
		if(!( la_sortie = fdopen( le_tube[SORTIE], "r" ))){
			printf( "Erreur dans fdopen();\n" );
			kill( le_pid_A, SIGKILL );
			kill( le_pid_B, SIGKILL );
			kill( le_pid_C, SIGKILL );
			}
		printf("\t\tFils C : debut de l'attente\n");
		traite_le_C();
		}
	sleep(1);
	printf("Le pere A : debut des echanges ...\n");
	traite_le_A();
	}
/* langage algorithmique
definition ENTREE 1
definition SORTIE 0
definition NL 10
variable globale toggle : entier
variable globale le_tube : tableau de 2 entier
variable globale la_sortie : pointeur de fichier
variable globale l_entree: pointeur de fichier
variable globale le_pid_A : pid_t
variable globale le_pid_B : pid_t
variable globale le_pid_C : pid_t
procedure traite_le_SUGUSR1_A()
debut
	affiche "Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)"
	toggle = negation de toggle
fin
procedure traite_le_SUGUSR2_A()
debut
	si toggle == 0
		affiche "Le pere A : signal recu de B : SIGUSR2"
		toggle = negation de toggle 
		affiche "Le pere A : envoie au fils C : SIGUSR2"
		emet au processus C le signal SIGUSR2
	fin de si
	si toggle == 1 	
		affiche "Le pere A : signal recu de C : SIGUSR2"
		affiche "Le pere A : Fin du fils B."
		emet au processus B le signal SIGKILL
		affiche "Le pere A : Fin du fils C."
		emet au processus C le signal SIGKILL
		affiche "Le pere A : Fin de moi !"
		emet au processus A le signal SIGKILL
	fin de si
	attend un message
fin
procedure traite_le_SUGUSR1_B()
variable i : entier
variable le_car : entier
variable le_buf : tableau de 100 caracteres 
debut 
	affiche "Le fils B : message a envoyer :" 
	tant que le_car = fgetc( stdin ) est different de NL et i est strictement inferieur ou egal a 99
		si le_car == EOF 
			ferme le_tube[ENTREE]
			affiche "Le fils B : envoie au pere A : SIGUSR2"
			emet au processus A le signal SIGUSR2
			attend un message
		fin de si
		fputc( le_car, l_entree )
		incremente i
	fin de tant que
	affiche "Le fils B : ecriture et envoie du message" 
	fputc( NL, l_entree )
	fflush( l_entree )
fin
procedure traite_le_SUGUSR1_C()
variable le_car : entier
variable premier : entier
debut
	affiche "Le fils C : signal recu : SIGUSR1"
	affiche "Le fils C : message recu : "
	tant que le_car = fgetc( la_sortie ) est different de NL 
		si le_car est strictement supperieur ou egal a 97 et le_car est strictement inferieur ou egal a 122
			le_car = le_car - 32
		fin de si	
		affiche le_car
		incremente premier
	fin de tant que
	si premier == 0  
		affiche "PAS DE MESSAGE"
	fin de si
	affiche saut de ligne
fin
procedure traite_le_SUGUSR2_C()
debut
	affiche "Le fils C : signal recu : SIGUSR2"
	ferme le_tube[SORTIE]
	affiche "Le fils C : envoie au pere A : SIGUSR2"
	emet au processus A le signal SIGUSR2
	attend un message
fin
procedure traite_le_A()
debut
	si reception du signal SIGUSR1 alors saute  traite_le_SIGUSR1_A()
	si reception du signal SIGUSR2 alors saute  traite_le_SIGUSR2_A()
	si toggle == 0
		affiche "Le pere A : signal envoye : SIGUSR1 (autorisation tache B)"
		emet au processus B le signal SIGUSR1
	sinon si toggle == 1
		affiche "Le pere A : signal envoye : SIGUSR1 (autorisation tache C)"
		emet au processus C le signal SIGUSR1
	fin de si
	attend un message
	traite_le_A()
fin
procedure traite_le_B()
debut
	si reception du signal SIGUSR1 alors saute  traite_le_SIGUSR1_B()
	attend un message
	affiche "Le fils B : envoie au pere A de SIGUSR1" 
	emet au processus A le signal SIGUSR1
	traite_le_B()
fin	
procedure traite_le_C()
debut
	si reception du signal SIGUSR1 alors saute  traite_le_SIGUSR1_C()
	si reception du signal SIGUSR2 alors saute  traite_le_SIGUSR2_C()
	attend un message
	affiche "Le fils C : envoie au pere A de SIGUSR1" 
	emet au processus A le signal SIGUSR1
	traite_le_C()
fin
procedure main()
debut
	si pipe( le_tube ) == -1
		affiche "Erreur dans pipe()"
		sortie
	fin de si
	le_pid_A = getpid()
	si le_pid_B = fork() == -1
		affiche "Erreur dans fork()"
		sortie
	sinon si le_pid_B == 0 
		affiche "Debut du fils B"
		ferme le_tube[SORTIE] )
		si echoue l_entree = ouvre le_tube[ENTREE] en mode ecriture
			affiche "Erreur dans fdopen()"
			emet au processus A le signal SIGKILL
			emet au processus B le signal SIGKILL
		fin de si echoue
		affiche "Fils B : debut de l'attente"
 		traite_le_B()
	fin de si
	attendre la mise en place de la fourche
	si le_pid_C = fork() == -1
		affiche "Erreur dans fork()"
		emet au processus B le signal SIGKILL
		sortie
	sinon si le_pid_C == 0 
		affiche "Debut du fils C"
		ferme le_tube[ENTREE]
		si echoue la_sortie = ouvre le_tube[SORTIE] en mode lecture
			affiche "Erreur dans fdopen()"
			emet au processus A le signal SIGKILL
			emet au processus B le signal SIGKILL
			emet au processus C le signal SIGKILL
		fin de si echoue
		affiche "Fils C : debut de l'attente"
		traite_le_C()
	fin de si
	attendre la mise en place de la fourche
	affiche "Le pere A : debut des echanges ..."
	traite_le_A()
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pp /usr/src/cours/devoir2/dev2ex2/projet/pp.c
[root@localhost /root]# pp
        Debut du fils B
        Fils B : debut de l'attente
                Debut du fils C
                Fils C : debut de l'attente
Le pere A : debut des echanges ...
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
        Le fils B : message a envoyer :exercice AA1254ww
        Le fils B : ecriture et envoie du message
        Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
                Le fils C : signal recu : SIGUSR1
                Le fils C : message recu : EXERCICE AA1254WW
                Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
        Le fils B : message a envoyer :
        Le fils B : ecriture et envoie du message
        Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
                Le fils C : signal recu : SIGUSR1
                Le fils C : message recu : PAS DE MESSAGE
                Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
        Le fils B : message a envoyer : '\n'
        Le fils B : ecriture et envoie du message
        Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
                Le fils C : signal recu : SIGUSR1
                Le fils C : message recu : PAS DE MESSAGE
                Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
        Le fils B : message a envoyer :sdgfsdg
        Le fils B : ecriture et envoie du message
        Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
                Le fils C : signal recu : SIGUSR1
                Le fils C : message recu : SDGFSDG
                Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
        Le fils B : message a envoyer : '^D'
        Le fils B : envoie au pere A : SIGUSR2
Le pere A : signal recu de B : SIGUSR2
Le pere A : envoie au fils C : SIGUSR2
                Le fils C : signal recu : SIGUSR2
                Le fils C : envoie au pere A : SIGUSR2
Le pere A : signal recu de C : SIGUSR2
Le pere A : Fin du fils B.
Le pere A : Fin du fils C.
Le pere A : Fin de moi !
Killed
[root@localhost /root]#  
*/