--- rpl/src/gestion_variables_statiques.c 2012/10/04 15:21:26 1.37 +++ rpl/src/gestion_variables_statiques.c 2013/04/01 15:29:34 1.48 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.11 - Copyright (C) 1989-2012 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.14 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -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; @@ -157,17 +118,48 @@ 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. - BUG((*l_variable_courante).noeuds[(*s_etat_processus) - .pointeurs_caracteres_variables[*ptr]] == NULL, - uprintf("Variable=\"%s\", (*ptr)='%c', nullified folder\n")); + 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++; + + // 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); } @@ -251,22 +304,29 @@ retrait_variable_statique(struct_process if ((*l_element_liste_a_supprimer).precedent != NULL) { + // L'élément à supprimer n'est pas le premier de la liste. + (*(*l_element_liste_a_supprimer).precedent).suivant = (*l_element_liste_a_supprimer).suivant; - } - else - { - (*(*l_element_liste_a_supprimer).suivant).precedent = NULL; - } - if ((*l_element_liste_a_supprimer).suivant != NULL) - { - (*(*l_element_liste_a_supprimer).suivant).precedent = - (*l_element_liste_a_supprimer).precedent; + if ((*l_element_liste_a_supprimer).suivant != NULL) + { + // Il y a un élément suivant. On le chaîne. + (*(*l_element_liste_a_supprimer).suivant).precedent = NULL; + } } else { - (*(*l_element_liste_a_supprimer).precedent).suivant = NULL; + // L'élement est le premier de la liste. S'il y a un élément + // suivant, on le chaîne. + + 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; } free(l_element_liste_a_supprimer); @@ -276,22 +336,32 @@ retrait_variable_statique(struct_process if ((*l_element_a_supprimer).precedent != NULL) { + // L'élément n'est pas le premier de la liste. + (*(*l_element_a_supprimer).precedent).suivant = (*l_element_a_supprimer).suivant; - } - else - { - (*(*l_element_a_supprimer).suivant).precedent = NULL; - } - if ((*l_element_a_supprimer).suivant != NULL) - { - (*(*l_element_a_supprimer).suivant).precedent = - (*l_element_a_supprimer).precedent; + if ((*l_element_a_supprimer).suivant != NULL) + { + (*(*l_element_a_supprimer).suivant).precedent = + (*l_element_a_supprimer).precedent; + } + else + { + (*(*l_element_a_supprimer).precedent).suivant = NULL; + } } else { - (*(*l_element_a_supprimer).precedent).suivant = NULL; + // L'élément est le premier de la liste. + + if ((*l_element_a_supprimer).suivant != NULL) + { + (*(*l_element_a_supprimer).suivant).precedent = NULL; + } + + (*(*l_element_a_supprimer).feuille).feuille_statique + = (*l_element_a_supprimer).suivant; } liberation(s_etat_processus, (*(*l_element_a_supprimer).variable) @@ -308,7 +378,7 @@ retrait_variable_statique(struct_process (*s_etat_processus).erreur_systeme = d_es_variable_introuvable; } - return erreur; + return(erreur); } @@ -377,7 +447,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 +458,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; } }