--- rpl/src/gestion_variables_statiques.c 2012/10/04 15:21:26 1.37 +++ rpl/src/gestion_variables_statiques.c 2012/10/07 08:18:35 1.38 @@ -25,47 +25,6 @@ /* ================================================================================ - Routine d'ajout d'un bouchon dans la liste des variables statiques -================================================================================ - Entrée : --------------------------------------------------------------------------------- - Sortie : --------------------------------------------------------------------------------- - Effets de bords : néant -================================================================================ -*/ - -// Routine ajoutant à la liste des variables statiques créées un 'bouchon' -// qui est un enregistrement dont la variable est NULL. Cela permet -// d'effacer les variables statiques créées dans une expression évaluées car, -// l'adresse de ces variables changeant à chaque évaluation, elles ne sont -// pas utilisables et constituent une fuite de mémoire - -logical1 -ajout_bouchon_variable_statique(struct_processus *s_etat_processus) -{ - struct_liste_variables_statiques *l_tete_liste; - - l_tete_liste = (*s_etat_processus).l_liste_variables_statiques; - - if (((*s_etat_processus).l_liste_variables_statiques = - malloc(sizeof(struct_liste_variables_statiques))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(d_erreur); - } - - (*(*s_etat_processus).l_liste_variables_statiques).variable = NULL; - (*(*s_etat_processus).l_liste_variables_statiques).suivant = l_tete_liste; - (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL; - (*l_tete_liste).precedent = (*s_etat_processus).l_liste_variables_statiques; - - return(d_absence_erreur); -} - - -/* -================================================================================ Routine de retrait des variables statiques ================================================================================ Entrée : @@ -76,41 +35,41 @@ ajout_bouchon_variable_statique(struct_p ================================================================================ */ -// Cette routine libère toutes les variables statiques jusqu'au prochain -// bouchon ou jusqu'à la fin de la liste si aucun bouchon n'est rencontré. +// Cette routine libère toutes les variables statiques de niveau non +// nul, donc attachées à une expression et non un programme. logical1 -retrait_variables_statiques(struct_processus *s_etat_processus) +retrait_variables_statiques_locales(struct_processus *s_etat_processus) { + struct_liste_variables_statiques *l_element_courant; + struct_liste_variables_statiques *l_element_suivant; + unsigned char registre_mode_execution; registre_mode_execution = (*s_etat_processus).mode_execution_programme; + l_element_courant = (*s_etat_processus).l_liste_variables_statiques; - while((*s_etat_processus).l_liste_variables_statiques != NULL) + while(l_element_courant != NULL) { + l_element_suivant = (*l_element_courant).suivant; + (*s_etat_processus).mode_execution_programme = - ((*(*(*s_etat_processus).l_liste_variables_statiques) - .variable).origine == 'P') ? 'Y' : 'N'; + ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N'; - if ((*(*s_etat_processus).l_liste_variables_statiques).variable == NULL) + if ((*(*l_element_courant).variable).niveau > 0) { - // On vient de tomber sur un bouchon... - (*s_etat_processus).l_liste_variables_statiques = - (*(*s_etat_processus).l_liste_variables_statiques).suivant; - free((*(*s_etat_processus).l_liste_variables_statiques).precedent); - (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL; - break; + if (retrait_variable_statique(s_etat_processus, + (*(*l_element_courant).variable).nom, + (*(*l_element_courant).variable).variable_statique) + == d_erreur) + { + (*s_etat_processus).mode_execution_programme = + registre_mode_execution; + return(d_erreur); + } } - if (retrait_variable_statique(s_etat_processus, (*(*(*s_etat_processus) - .l_liste_variables_statiques).variable).nom, - (*(*(*s_etat_processus).l_liste_variables_statiques).variable) - .variable_statique) == d_erreur) - { - (*s_etat_processus).mode_execution_programme = - registre_mode_execution; - return(d_erreur); - } + l_element_courant = l_element_suivant; } (*s_etat_processus).mode_execution_programme = registre_mode_execution; @@ -134,6 +93,8 @@ logical1 creation_variable_statique(struct_processus *s_etat_processus, struct_variable_statique *s_variable) { + int i; + struct_arbre_variables *l_variable_courante; struct_liste_variables_statiques *l_nouvel_element; @@ -142,6 +103,7 @@ creation_variable_statique(struct_proces // Ajout de la variable en tête de la liste des variables statiques +printf("<0>\n"); if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques))) == NULL) { @@ -159,15 +121,45 @@ creation_variable_statique(struct_proces (*(*l_nouvel_element).variable) = (*s_variable); (*l_nouvel_element).suivant = (*s_etat_processus) .l_liste_variables_statiques; - (*(*s_etat_processus).l_liste_variables_statiques).precedent - = l_nouvel_element; (*l_nouvel_element).precedent = NULL; + + if ((*s_etat_processus).l_liste_variables_statiques != NULL) + { + (*(*s_etat_processus).l_liste_variables_statiques).precedent + = l_nouvel_element; + } + (*s_etat_processus).l_liste_variables_statiques = l_nouvel_element; // Ajout de la variable à la feuille statique de l'arbre des variables - BUG((*s_etat_processus).s_arbre_variables == NULL, - uprintf("(*s_etat_processus).s_arbre_variables=NULL\n")); + if ((*s_etat_processus).s_arbre_variables == NULL) + { + if (((*s_etat_processus).s_arbre_variables = + allocation_noeud(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(d_erreur); + } + + (*(*s_etat_processus).s_arbre_variables).feuille = NULL; + (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL; + (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0; + (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1; + (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL; + + if (((*(*s_etat_processus).s_arbre_variables).noeuds = + allocation_tableau_noeuds(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(d_erreur); + } + + for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) + { + (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL; + } + } l_variable_courante = (*s_etat_processus).s_arbre_variables; ptr = (*s_variable).nom; @@ -178,12 +170,67 @@ creation_variable_statique(struct_proces uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom, *ptr)); - // La feuille doit préexister car la variable statique est toujours - // créée depuis une variable locale. + if ((*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]] == NULL) + { + // Le noeud n'existe pas encore, on le crée et on le marque + // comme utilisé dans la structure parente. + + if (((*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]] = + allocation_noeud(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(d_erreur); + } + + (*l_variable_courante).noeuds_utilises++; - BUG((*l_variable_courante).noeuds[(*s_etat_processus) - .pointeurs_caracteres_variables[*ptr]] == NULL, - uprintf("Variable=\"%s\", (*ptr)='%c', nullified folder\n")); + // La feuille est par défaut vide et aucun élément du tableau noeuds + // (les branches qui peuvent être issues de ce nouveau noeud) + // n'est encore utilisée. + + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).feuille = NULL; + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).feuille_statique + = NULL; + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0; + + // Le champ noeud_pere de la structure créée pointe sur + // la structure parente et l'indice tableau_pere correspond à la + // position réelle dans le tableau noeuds[] de la structure parente + // du noeud courant. Cette valeur sera utilisée lors de la + // destruction du noeud pour annuler le pointeur contenu dans + // le tableau noeuds[] de la structure parente. + + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).noeud_pere = + l_variable_courante; + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]) + .indice_tableau_pere = (*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]; + + // Allocation du tableau noeuds[] et initialisation à zéro de + // tous les pointeurs. + + if (((*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).noeuds = + allocation_tableau_noeuds(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(d_erreur); + } + + for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) + { + (*(*l_variable_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres_variables[*ptr]]).noeuds[i] + = NULL; + } + } l_variable_courante = (*l_variable_courante).noeuds [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]]; @@ -204,13 +251,19 @@ creation_variable_statique(struct_proces (*l_nouvel_element).suivant = (*l_variable_courante).feuille_statique; (*l_nouvel_element).precedent = NULL; - (*(*l_nouvel_element).suivant).precedent = l_nouvel_element; + + if ((*l_nouvel_element).suivant != NULL) + { + (*(*l_nouvel_element).suivant).precedent = l_nouvel_element; + } (*l_nouvel_element).reference = (*s_etat_processus).l_liste_variables_statiques; (*l_nouvel_element).variable = (*(*s_etat_processus) .l_liste_variables_statiques).variable; (*l_variable_courante).feuille_statique = l_nouvel_element; + (*l_nouvel_element).feuille = l_variable_courante; + return(d_absence_erreur); } @@ -236,10 +289,12 @@ retrait_variable_statique(struct_process logical1 erreur; +printf("<1>\n"); if ((l_element_a_supprimer = recherche_variable_statique(s_etat_processus, nom_variable, position, ((*s_etat_processus) .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL) { +printf("<2>\n"); // (*s_etat_processus).pointeur_variable_statique_courante // pointe sur la variable à éliminer. Cette variable est celle qui // est présente dans l'une des feuilles statiques de l'arbre des @@ -256,7 +311,13 @@ retrait_variable_statique(struct_process } else { - (*(*l_element_liste_a_supprimer).suivant).precedent = NULL; + if ((*l_element_liste_a_supprimer).suivant != NULL) + { + (*(*l_element_liste_a_supprimer).suivant).precedent = NULL; + } + + (*s_etat_processus).l_liste_variables_statiques = + (*l_element_liste_a_supprimer).suivant; } if ((*l_element_liste_a_supprimer).suivant != NULL) @@ -282,6 +343,8 @@ retrait_variable_statique(struct_process else { (*(*l_element_a_supprimer).suivant).precedent = NULL; + (*(*l_element_a_supprimer).feuille).feuille_statique + = (*l_element_a_supprimer).suivant; } if ((*l_element_a_supprimer).suivant != NULL) @@ -377,7 +440,7 @@ recherche_variable_statique(struct_proce ((*(*l_element_courant).variable).origine == origine)) { (*s_etat_processus).pointeur_variable_statique_courante - = (*l_element_courant).variable; + = (*l_element_courant).variable; return(l_element_courant); } } @@ -388,10 +451,12 @@ recherche_variable_statique(struct_proce ((*(*l_element_courant).variable).origine == origine)) { (*s_etat_processus).pointeur_variable_statique_courante - = (*l_element_courant).variable; + = (*l_element_courant).variable; return(l_element_courant); } } + + l_element_courant = (*l_element_courant).suivant; } }