/*************************************** * * * Copyright (c) 1998 Jean-Eric Pin * * All rights reserved. * * * * TAB = 2 spaces * * * ***************************************/ /*------------------------------------------------------------------- * Memoire.c Jean-Eric Pin 07/12/96 *------------------------------------------------------------------- */ #include <stdlib.h> #include <stdio.h> #include <memory.h> #include "Main.h" #include "Globales.h" #include "Initialisation.h" #include "InitLaTeX.h" #include "Inverses.h" #include "Matrices.h" #include "MatricesBooleennes.h" #include "MatricesMaxPlus.h" #include "Memoire.h" #include "Transitions.h" #include "Utilitaires.h" #ifdef DEBUG extern long ElementsAlloues; #endif /* DEBUG */ extern unsigned long *TableDeHachage; /* La table de l'adresse des elements. On y accede par hachage et adressage ouvert. */ extern unsigned long *TableIdempotents; /* La table des idempotents */ extern unsigned long *B; /* La table des blocs */ extern unsigned long NbElements, TailleMaxi; extern unsigned long TailleTableDeHachage; extern info *Table; extern info2 *Table2; extern ProduitsDG *TableInfo; /* extern lettre *Mot; */ extern unsigned short NbEtats, NbLettres, MemoireAllouee, MemoireInitiauxAllouee, MemoireFinauxAllouee; extern unsigned long CalculsEffectues; extern element Identite; extern element *Generateurs; extern element *TableDesValeurs; /* Les valeurs des elements du semigroupe dans l'univers. */ extern Alloue_ AlloueMemoireGenerateur; extern Libere_ LibereMemoireElement, LibereMemoireGenerateur; extern char **Messages; extern infoSommet **Graphe; /* Le graphe syntactique */ extern Liste2Numeros PileGraphe; /* Pile utilisee pour le parcours en profondeur du graphe. */ extern unsigned long **TableDeS; /* La table de multiplication du semigroupe */ extern unsigned short *EtatsInitiaux, *EtatsFinaux; extern long *TableauLongueurMots; extern struct NumeroEtLettre *PileInverses; extern ListeNumero *Inverses, *InversesFaibles; extern adresses Adresses; /**************************************************** * * AlloueMemoireAdresses. OK * ****************************************************/ void AlloueMemoireAdresses(void) { Adresses.commutatif_1 = (lettre *)malloc(sizeof(lettre)); if (Adresses.commutatif_1 == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.commutatif_2 = (lettre *)malloc(sizeof(lettre)); if (Adresses.commutatif_2 == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.idempotent = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.idempotent == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.aperiodique = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.aperiodique == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.DA_x = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.DA_x == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.DA_y = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.DA_y == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.DS_x = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.DS_x == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.DS_y = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.DS_y == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.RvL_x = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.RvL_x == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.RvL_y = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.RvL_y == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.RvL_z = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.RvL_z == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.L1_s = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.L1_s == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.L1_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.L1_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.LG_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.L1_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.LG_s = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.L1_s == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_p = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_p == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_q = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_q == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_r = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_r == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_s = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_s == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1_f = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1_f == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1Plus_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1Plus_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.B1Plus_s = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.B1Plus_s == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.ECom_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.ECom_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.ECom_f = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.ECom_f == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.BG_e = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.BG_e == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } Adresses.BG_f = (unsigned long *)malloc(sizeof(unsigned long)); if (Adresses.BG_f == NULL) { printf("%s \n", Messages[M_Pb_memory]); exit(1); } } /**************************************************** * * LibereMemoireAdresses. OK * ****************************************************/ void LibereMemoireAdresses(void) { free(Adresses.commutatif_1); free(Adresses.commutatif_2); free(Adresses.idempotent); free(Adresses.aperiodique); free(Adresses.DA_x); free(Adresses.DA_y); free(Adresses.DS_x); free(Adresses.DS_y); free(Adresses.RvL_x); free(Adresses.RvL_y); free(Adresses.RvL_z); free(Adresses.L1_e); free(Adresses.L1_s); free(Adresses.LG_e); free(Adresses.LG_s); free(Adresses.B1_p); free(Adresses.B1_q); free(Adresses.B1_r); free(Adresses.B1_s); free(Adresses.B1_e); free(Adresses.B1_f); free(Adresses.B1Plus_e); free(Adresses.B1Plus_s); free(Adresses.ECom_e); free(Adresses.ECom_f); free(Adresses.BG_e); free(Adresses.BG_f); } /**************************************************** * * AlloueMemoireProduits. OK * Necessite de connaitre le nombre de lettres * ****************************************************/ ProduitsDG *AlloueMemoireProduits(void) { register ProduitsDG *Produits; Produits = ALLOC(ProduitsDG, NbLettres); if (Produits == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_products]); /* Probleme lors de l'allocation memoire des produits */ exit(1); } return Produits; } /**************************************************** * * AlloueMemoireGenerateurs. OK * ****************************************************/ void AlloueMemoireGenerateurs(void) { lettre a; if (!(MemoireAllouee & MEMOIRE_GENERATEURS)) { Generateurs = ALLOC(element, NbLettres); if (Generateurs == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_generators]); /* Probleme lors de l'allocation memoire des generateurs */ exit(1); } for (a = 0; a < NbLettres; a++) Generateurs[a] = AlloueMemoireGenerateur(); MemoireAllouee |= MEMOIRE_GENERATEURS; /* On prend note : on a alloue de la memoire aux generateurs. */ } #ifdef DEBUG else printf("La memoire des generateurs est deja allouee !\n"); #endif /* DEBUG */ } /**************************************************** * * LibereMemoireGenerateurs. OK * ****************************************************/ void LibereMemoireGenerateurs(void) { lettre a; if (MemoireAllouee & MEMOIRE_GENERATEURS) { for (a = 0; a < NbLettres; a++) LibereMemoireGenerateur(Generateurs[a]); free(Generateurs); MemoireAllouee &= ~MEMOIRE_GENERATEURS; /* On prend note : on a libere la memoire des generateurs. */ } } /*********************************************************************************** * * AlloueMemoireTableDesValeurs. OK * TableDesValeurs[1] donne l'identite. * S'il y a 2 generateurs, leurs valeurs seront stockees * en TableDesValeurs[2] et TableDesValeurs[3]. * * Cette procedure est necessairement appelee AVANT InitIdentite et InitGenerateurs() * ************************************************************************************/ void AlloueMemoireTableDesValeurs(void) { if (!(MemoireAllouee & MEMOIRE_TABLE_VALEURS)) { TableDesValeurs = ALLOC(element, 2 + TailleMaxi); if (TableDesValeurs == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table_elements]); /* Probleme lors de l'allocation memoire de la table des elements */ exit(1); } MemoireAllouee |= MEMOIRE_TABLE_VALEURS; /* On prend note : on a alloue de la memoire aux generateurs. */ } #ifdef DEBUG else printf("La memoire de la table des valeurs est deja allouee !\n"); #endif /* DEBUG */ } /**************************************************** * * LibereMemoireTableDesValeurs. OK * ****************************************************/ void LibereMemoireTableDesValeurs(void) { unsigned long i; if (MemoireAllouee & MEMOIRE_TABLE_VALEURS) { for (i = 1; i <= NbElements; i++) LibereMemoireElement(TableDesValeurs[i]); free(TableDesValeurs); MemoireAllouee &= ~MEMOIRE_TABLE_VALEURS; /* On prend note : on a libere la memoire de la table. */ } } /**************************************************** * * AlloueMemoirePile. OK * ****************************************************/ elementpile *AlloueMemoirePile(void) { elementpile *Pile; if (!(MemoireAllouee & MEMOIRE_PILE)) { Pile = ALLOC(elementpile, NbElements); if (Pile == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire d'un tableau */ return 0; } MemoireAllouee |= MEMOIRE_PILE; /* On prend note : on a alloue de la memoire aux generateurs. */ return Pile; } #ifdef DEBUG else { printf("La memoire de la pile est deja allouee !\n"); return 0; } #endif /* DEBUG */ } /**************************************************** * * AlloueMemoirePileComposanteConnexe. OK * ****************************************************/ unsigned long *AlloueMemoirePileComposanteConnexe(void) { unsigned long *PileComposanteConnexe; PileComposanteConnexe = ALLOC(unsigned long, NbElements + 1); /* +1, car on met une sentinelle en fond de pile */ if (PileComposanteConnexe == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire d'un tableau */ return 0; } return PileComposanteConnexe; } /**************************************************** * * AlloueMemoireTableau. OK * ****************************************************/ unsigned long *AlloueMemoireTableau(unsigned long Taille) { unsigned long *MyTableau; MyTableau = ALLOC(unsigned long, Taille); if (MyTableau == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire d'un tableau */ return 0; } return MyTableau; } /**************************************************** * * AlloueMemoireTable. OK * ****************************************************/ info *AlloueMemoireTable(void) { info *MyTable; MyTable = ALLOC(info, 1 + TailleMaxi); if (MyTable == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table_elements]); /* Probleme lors de l'allocation memoire de la table des elements */ exit(1); } return(MyTable); } /**************************************************** * * AlloueMemoireTable2. OK * ****************************************************/ info2 *AlloueMemoireTable2(void) { info2 *MyTable2; MyTable2 = ALLOC(info2, 1 + NbElements); if (MyTable2 == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table_elements]); /* Probleme lors de l'allocation memoire de la table des elements */ exit(1); } return(MyTable2); } /********************************************************* * * AlloueMemoireMot. Ajoute la place pour terminer par '\0' * *********************************************************/ lettre *AlloueMemoireMot(short Longueur) { lettre *Mot; Mot = ALLOC(lettre, 1 + Longueur); /* Un de plus, pour terminer par '\0' */ if (Mot == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_word]); /* Probleme lors de l'allocation memoire d'un mot */ exit(1); } return(Mot); } /**************************************************** * * AlloueMemoireLettre. OK * ****************************************************/ lettre *AlloueMemoireLettre(void) { lettre *Mot; Mot = ALLOC(lettre, 2); /* Un de plus, pour terminer par '\0' */ if (Mot == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_word]); /* Probleme lors de l'allocation memoire d'un mot */ exit(1); } return(Mot); } /********************************************************************** * * AlloueMemoireChaine. * **********************************************************************/ char *AlloueMemoireChaine(short Longueur) { char *Chaine; Chaine = ALLOC(char, Longueur); if (Chaine == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_word]); /* Probleme lors de l'allocation memoire d'un mot. */ exit(1); } return(Chaine); } /********************************************************************** * * AlloueMemoireGraphe. Comme les indices partent de 1, * on prend un graphe de taille (1 + NbElements) * (1 + NbElements). * Les entrees Graphe[0][v] et Graphe[u][0] ne servent pas. * **********************************************************************/ void AlloueMemoireGraphe(void) { unsigned long j; Graphe = ALLOC(infoSommet *, (1 + NbElements)); if (Graphe == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_graph]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } for (j = 0; j < 1 + NbElements; j++) { Graphe[j] = ALLOC(infoSommet, 1 + NbElements); if (Graphe[j] == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_graph]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } } } /********************************************************************** * * LibereMemoireGraphe. * **********************************************************************/ void LibereMemoireGraphe(void) { unsigned long u, v; Liste2Numeros Temporaire; for (u = 0; u <= NbElements; u++) for (v = 0; v <= NbElements; v++) while (Graphe[u][v].Aretes != NULL) { Temporaire = Graphe[u][v].Aretes; Graphe[u][v].Aretes = Graphe[u][v].Aretes->suivant; free(Temporaire); } for (u = 0; u <= NbElements; u++) free(Graphe[u]); free(Graphe); } /**************************************************** * * AlloueMemoirePileGraphe. OK * ****************************************************/ Liste2Numeros AlloueMemoirePileGraphe(unsigned long Taille) { Liste2Numeros MyPileGraphe; MyPileGraphe = ALLOC(struct Wagon2Numeros, Taille); if (MyPileGraphe == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire d'un tableau */ return 0; } return MyPileGraphe; } /**************************************************** * * AlloueMemoireArete. * ****************************************************/ Liste2Numeros AlloueMemoireArete(void) { Liste2Numeros Liste; Liste = ALLOC(struct Wagon2Numeros, 1); if (Liste == NULL) { printf("%s %s xxx\n", Messages[M_Pb_memory], Messages[M_Pb_graph]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } return(Liste); } /**************************************************** * * AlloueMemoireTableDeS. * ****************************************************/ unsigned long **AlloueMemoireTableDeS(void) { unsigned long **MyTable; unsigned long i; MyTable = ALLOC(unsigned long *, 1 + NbElements); if (MyTable == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } for (i = 0; i <= NbElements; i++) { MyTable[i] = ALLOC(unsigned long, 1 + NbElements); if (MyTable[i] == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } } return(MyTable); } /**************************************************** * * LibereMemoireTableDeS. * ****************************************************/ void LibereMemoireTableDeS(void) { unsigned long i; for (i = 0; i <= NbElements; i++) free(TableDeS[i]); free(TableDeS); } /**************************************************** * * AlloueMemoirePileNumeroEtLettre. OK * ****************************************************/ struct NumeroEtLettre *AlloueMemoirePileNumeroEtLettre(void) { struct NumeroEtLettre *Pile; Pile = ALLOC(struct NumeroEtLettre, NbElements); if (Pile == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_table]); /* Probleme lors de l'allocation memoire d'un tableau */ return 0; } return Pile; } /********************************************************************** * * AlloueMemoireTableListeNumero. * **********************************************************************/ ListeNumero *AlloueMemoireTableListeNumero(void) { ListeNumero *MyTable; MyTable = ALLOC(ListeNumero, 1 + NbElements); /* Les indices commencent a 1 ... */ if (MyTable == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_liste]); /* Probleme lors de l'allocation memoire d'une liste. */ exit(1); } return(MyTable); } /**************************************************** * * AlloueMemoireWagonNumero. * ****************************************************/ ListeNumero AlloueMemoireWagonNumero(void) { ListeNumero Liste; Liste = ALLOC(struct WagonNumero, 1); if (Liste == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_graph]); /* Probleme lors de l'allocation memoire du graphe. */ exit(1); } return(Liste); } /**************************************************** * * LibereMemoireMot. OK * ****************************************************/ void LibereMemoireMot(element Element) { free(Element); } /********************************************************************** * * LibereMemoireListe. * **********************************************************************/ void LibereMemoireListe(ListeNumero *MyList) { unsigned long u; ListeNumero Temporaire; for (u = 0; u <= NbElements; u++) while (MyList[u] != NULL) { Temporaire = MyList[u]; MyList[u] = MyList[u]->suivant; free(Temporaire); } free(MyList); } /********************************************************************** * * AlloueMemoireInitiaux. * **********************************************************************/ void AlloueMemoireInitiaux(void) { EtatsInitiaux = ALLOC(unsigned short, (1 + NbEtats)); /* Initialisation a 0 automatique */ MemoireInitiauxAllouee = 1; if (EtatsInitiaux == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_initial_states]); /* Probleme lors de l'allocation memoire des etats initiaux. */ exit(1); } } /********************************************************************** * * AlloueMemoireFinaux. * **********************************************************************/ void AlloueMemoireFinaux(void) { EtatsFinaux = ALLOC(unsigned short, (1 + NbEtats)); /* Initialisation a 0 automatique */ MemoireFinauxAllouee = 1; if (EtatsFinaux == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_final_states]); /* Probleme lors de l'allocation memoire des etats finaux. */ exit(1); } } /********************************************************************** * * AlloueMemoireMessages. * **********************************************************************/ void AlloueMemoireMessages(void) { Messages = ALLOC(char *, M_Last_Line); if (Messages == NULL) { printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_messages]); /* Probleme lors de l'allocation memoire des messages. */ exit(1); } } /**************************************************** * * LibereMemoire. OK * free(TableDeHachage) est fait independamment * LibereMemoireGenerateurs() est inutile, car les * generateurs sont stockes dans la table des valeurs * ****************************************************/ void LibereMemoire(void) { unsigned long i; LibereMemoireGenerateurs(); for (i = NbElements; i > 0; i--) free(Table[i].Produits); free(Table[0].Produits); /* i est de type unsigned long : si i vaut 0, i-- est > 0 ! */ free(Table); free(Table2); LibereMemoireTableDesValeurs(); LibereMemoireAdresses(); if (CalculsEffectues & CALCUL_LISTE_IDEMPOTENTS) free(TableIdempotents); if (CalculsEffectues & CALCUL_SYNTACTIQUE) LibereMemoireGraphe(); if (CalculsEffectues & CALCUL_TABLE_DE_S) LibereMemoireTableDeS(); if (CalculsEffectues & CALCUL_BLOCS) free(B); if (CalculsEffectues & CALCUL_INVERSES) { free(PileInverses); LibereMemoireListe(Inverses); LibereMemoireListe(InversesFaibles); } if (CalculsEffectues & CALCUL_SYNTACTIQUE) free(PileGraphe); if (MemoireInitiauxAllouee) { free(EtatsInitiaux); MemoireInitiauxAllouee = 0; } if (MemoireFinauxAllouee) { free(EtatsFinaux); MemoireFinauxAllouee = 0; } if (MemoireAllouee & MEMOIRE_TABLEAU_LONGUEUR_MOTS) { free(TableauLongueurMots); MemoireAllouee &= ~MEMOIRE_TABLEAU_LONGUEUR_MOTS; /* On prend note : on a libere la memoire de la table. */ } #ifdef DEBUG printf("Elements Alloues : %ld \n", ElementsAlloues); #endif /* DEBUG */ }