Diff for /rpl/src/gestion_variables.c between versions 1.32 and 1.33

version 1.32, 2011/06/17 08:47:43 version 1.33, 2011/06/19 17:48:27
Line 25 Line 25
   
 /*  /*
 ================================================================================  ================================================================================
     Fonction de debug
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
   static void
   liste_variables_par_niveaux(struct_processus *s_etat_processus)
   {
       int                     c;
   
       logical1                fin;
   
       struct_liste_variables  *l;
   
       struct_liste_chainee    *e;
   
       printf("===========================================================\n");
       printf("  Liste des variables par niveaux\n");
       printf("===========================================================\n");
   
       printf("Backward\n");
       l = (*s_etat_processus).l_liste_variables_par_niveau;
       c = 0;
       fin = d_faux;
   
       do
       {
           l = l->precedent;
           e = l->liste;
   
           while(e != NULL)
           {
               printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
                       e->donnee, ((struct_variable *) e->donnee)->niveau);
               e = e->suivant;
               c++;
               if (c > 100)
               {
                   fin = d_vrai;
                   break;
               }
           }
   
           printf("\n");
   
       } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
   
       printf("Forward\n");
       l = (*s_etat_processus).l_liste_variables_par_niveau;
       c = 0;
   
       do
       {
           e = l->liste;
   
           while(e != NULL)
           {
               printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
                       e->donnee, ((struct_variable *) e->donnee)->niveau);
               e = e->suivant;
               c++;
               if (c > 100) exit(0);
           }
   
           printf("\n");
   
           l = l->suivant;
       } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
   
       printf("===========================================================\n");
   
       if (fin == d_vrai) exit(0);
   
       return;
   }
   
   static void
   liste_variables_tas(struct_processus *s_etat_processus,
           struct_arbre_variables *arbre)
   {
       int                     c;
       int                     i;
   
       logical1                fin;
   
       struct_liste_variables  *l;
   
       fin = d_faux;
   
       if ((*arbre).feuille != NULL)
       {
           printf("Feuille %p\n", (*arbre).feuille);
   
           printf("  Backward\n");
   
           l = (*arbre).feuille;
           c = 0;
           fin = d_faux;
   
           do
           {
               l = l->precedent;
               c++;
               if (c > 100)
               {
                   fin = d_vrai;
                   break;
               }
               printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
                       l->variable->niveau);
           } while((*arbre).feuille != l);
   
           printf("  Forward\n");
   
           l = (*arbre).feuille;
           c = 0;
   
           do
           {
               c++;
               if (c > 100) exit(0);
               printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
                       l->variable->niveau);
               l = l->suivant;
           } while((*arbre).feuille != l);
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*arbre).noeuds[i] != NULL)
           {
               liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
           }
       }
   
       if (fin == d_vrai) exit(0);
   
       return;
   }
   
   
   static void
   liste_variables_par_feuilles(struct_processus *s_etat_processus)
   {
       printf("===========================================================\n");
       printf("  Liste des variables sur le tas\n");
       printf("===========================================================\n");
   
       liste_variables_tas(s_etat_processus,
               (*s_etat_processus).s_arbre_variables);
   
       printf("===========================================================\n");
   
       return;
   }
   
   
   /*
   ================================================================================
   Routine de création d'une nouvelle variable    Routine de création d'une nouvelle variable
   Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.  ================================================================================
   Dans le cas 'V', la variable est volatile.    Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
   Dans le cas 'S', elle est statique.    dans le cas 'v', la variable est volatile.
   Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.    dans le cas 's', elle est statique.
   Dans le cas 'P', la variable est privée.    Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
   Dans le cas 'S', elle est partagée.    dans le cas 'p', la variable est privée.
     dans le cas 's', elle est partagée.
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Sortie :    Sortie :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
Line 44  ajout_variable(struct_processus *s_etat_ Line 209  ajout_variable(struct_processus *s_etat_
 {  {
     int                         i;      int                         i;
   
       logical1                    niveau_acceptable;
   
     struct_liste_variables      *l_nouvelle_variable;      struct_liste_variables      *l_nouvelle_variable;
     struct_liste_variables      *l_variable_candidate;      struct_liste_variables      *l_variable_candidate;
   
     struct_arbre_variables      *l_variable_courante;      struct_arbre_variables      *l_variable_courante;
     struct_arbre_variables      *l_variable_precedente;      struct_arbre_variables      *l_variable_precedente;
   
Line 220  ajout_variable(struct_processus *s_etat_ Line 388  ajout_variable(struct_processus *s_etat_
             (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)              (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
                     .precedent;                      .precedent;
             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;              (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
               (*l_nouvelle_variable).noeud = l_variable_courante;
             (*(*(*l_variable_courante).feuille).precedent).suivant =              (*(*(*l_variable_courante).feuille).precedent).suivant =
                     l_nouvelle_variable;                      l_nouvelle_variable;
             (*(*l_variable_courante).feuille).precedent =              (*(*l_variable_courante).feuille).precedent =
Line 272  ajout_variable(struct_processus *s_etat_ Line 441  ajout_variable(struct_processus *s_etat_
             (*l_nouvelle_variable).precedent = (*l_variable_candidate)              (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                     .precedent;                      .precedent;
             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;              (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
               (*l_nouvelle_variable).noeud = l_variable_courante;
             (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;              (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
             (*l_variable_candidate).precedent = l_nouvelle_variable;              (*l_variable_candidate).precedent = l_nouvelle_variable;
   
Line 308  ajout_variable(struct_processus *s_etat_ Line 478  ajout_variable(struct_processus *s_etat_
         (*l_nouvelle_variable).liste = NULL;          (*l_nouvelle_variable).liste = NULL;
   
         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;          (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
   
           // Ajout de la variable en tête de la liste
   
           if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return(d_erreur);
           }
   
           (*l_nouvel_element).suivant = (*(*s_etat_processus)
                   .l_liste_variables_par_niveau).liste;
           (*l_nouvel_element).donnee = pointeur_variable_cree;
           (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                   l_nouvel_element;
     }      }
     else if ((*s_variable).niveau > (*((struct_variable *)      else if ((*s_variable).niveau > (*((struct_variable *)
             (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)              (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
Line 330  ajout_variable(struct_processus *s_etat_ Line 514  ajout_variable(struct_processus *s_etat_
         (*l_nouvelle_variable).liste = NULL;          (*l_nouvelle_variable).liste = NULL;
         (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)          (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
                 .suivant = l_nouvelle_variable;                  .suivant = l_nouvelle_variable;
         (*(*s_etat_processus).l_liste_variables_par_niveau).precedent =          (*(*s_etat_processus).l_liste_variables_par_niveau)
                 l_nouvelle_variable;                  .precedent = l_nouvelle_variable;
   
         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;          (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
     }  
     else if ((*s_variable).niveau <= 1)  
     {  
         // Création d'une variable de niveau 0 ou 1  
   
         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))          // Ajout de la variable en tête de la liste
                 == NULL)  
           if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return(d_erreur);              return(d_erreur);
         }          }
   
           (*l_nouvel_element).suivant = (*(*s_etat_processus)
                   .l_liste_variables_par_niveau).liste;
           (*l_nouvel_element).donnee = pointeur_variable_cree;
           (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                   l_nouvel_element;
       }
       else if ((*s_variable).niveau <= 1)
       {
           // Création d'une variable de niveau 0 ou 1. Il convient de
           // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
           // regarde la position courante et les deux précédentes.
   
         l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;          l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
           niveau_acceptable = d_faux;
   
         if ((*((struct_variable *) (*(*(*(*s_etat_processus)          for(i = 0; i <= 2; i++)
                 .l_liste_variables_par_niveau).precedent).liste).donnee))  
                 .niveau <= 1)  
         {          {
             l_variable_candidate = (*(*s_etat_processus)              if ((*l_variable_candidate).liste == NULL)
                     .l_liste_variables_par_niveau).precedent;              {
                   continue;
               }
   
               if ((*((struct_variable *) (*(*l_variable_candidate)
                       .liste).donnee)).niveau == (*s_variable).niveau)
               {
                   niveau_acceptable = d_vrai;
                   break;
               }
   
               l_variable_candidate = (*l_variable_candidate).precedent;
         }          }
   
         (*l_nouvelle_variable).suivant = l_variable_candidate;          if (niveau_acceptable == d_faux)
         (*l_nouvelle_variable).precedent = (*l_variable_candidate)          {
                 .precedent;              if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
         (*l_nouvelle_variable).noeud_pere = NULL;                      == NULL)
         (*l_nouvelle_variable).liste = NULL;              {
         (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         (*l_variable_candidate).precedent = l_nouvelle_variable;                  return(d_erreur);
     }              }
   
     // Ajout de la variable en tête de la liste              l_variable_candidate =
                       (*(*s_etat_processus).l_liste_variables_par_niveau)
                       .precedent;
   
     if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)              // On ne peut créer qu'une variable de niveau supérieur ou égal à
     {              // 1 lors de l'exécution normale d'un programme. Les variables
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              // de niveau 0 sont créées à l'initialisation et relèvent du
         return(d_erreur);              // cas précédent car il n'existe lors de leur création aucun
               // niveau non nul.
   
               BUG((*s_variable).niveau == 0,
                       uprintf("Attempt to create a level-0 variable!\n"));
   
               (*l_nouvelle_variable).suivant = l_variable_candidate;
               (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                       .precedent;
               (*l_nouvelle_variable).noeud_pere = NULL;
               (*l_nouvelle_variable).liste = NULL;
               (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
               (*l_variable_candidate).precedent = l_nouvelle_variable;
   
               l_variable_candidate = l_nouvelle_variable;
           }
   
           // Ajout de la variable en tête de la liste l_variable_candidate.
   
           if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return(d_erreur);
           }
   
           (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
           (*l_nouvel_element).donnee = pointeur_variable_cree;
           (*l_variable_candidate).liste = l_nouvel_element;
     }      }
       else
       {
           // Ajout de la variable en tête de la liste
   
     (*l_nouvel_element).suivant = (*(*s_etat_processus)          if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
             .l_liste_variables_par_niveau).liste;          {
     (*l_nouvel_element).donnee = pointeur_variable_cree;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
     (*(*s_etat_processus).l_liste_variables_par_niveau).liste =              return(d_erreur);
             l_nouvel_element;          }
   
           (*l_nouvel_element).suivant = (*(*s_etat_processus)
                   .l_liste_variables_par_niveau).liste;
           (*l_nouvel_element).donnee = pointeur_variable_cree;
           (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                   l_nouvel_element;
       }
   
     return(d_absence_erreur);      return(d_absence_erreur);
 }  }
Line 617  recherche_variable(struct_processus *s_e Line 859  recherche_variable(struct_processus *s_e
                 (*s_etat_processus).pointeur_variable_courante =                  (*s_etat_processus).pointeur_variable_courante =
                         (*(*(*l_variable_courante).feuille).precedent).variable;                          (*(*(*l_variable_courante).feuille).precedent).variable;
                 (*s_etat_processus).pointeur_feuille_courante =                  (*s_etat_processus).pointeur_feuille_courante =
                         (*l_variable_courante).feuille;                          (*(*l_variable_courante).feuille).precedent;
   
                 // S'il existe une variable de niveau 0 et une seconde de                  // S'il existe une variable de niveau 0 et une seconde de
                 // niveau 1, la variable de niveau 0 (fonction) est masquée                  // niveau 1, la variable de niveau 0 (fonction) est masquée
                 // par celle de niveau 1.                  // par celle de niveau 1.
   
                 if (((*(*(*l_variable_courante).feuille).variable).niveau == 0)                  if (((*(*(*(*l_variable_courante).feuille).precedent)
                         && ((*(*(*(*l_variable_courante).feuille).precedent)                          .variable).niveau == 0) && ((*(*(*(*
                           (*l_variable_courante).feuille).precedent).precedent)
                         .variable).niveau == 1))                          .variable).niveau == 1))
                 {                  {
                     (*s_etat_processus).pointeur_variable_courante =                      (*s_etat_processus).pointeur_variable_courante =
                             (*(*(*l_variable_courante).feuille).precedent)                              (*(*(*(*l_variable_courante).feuille).precedent)
                             .variable;                              .precedent).variable;
                     (*s_etat_processus).pointeur_feuille_courante =                      (*s_etat_processus).pointeur_feuille_courante =
                             (*l_variable_courante).feuille;                              (*(*(*l_variable_courante).feuille).precedent)
                               .precedent;
                 }                  }
   
                 return(d_vrai);                  return(d_vrai);
Line 658  recherche_variable_globale(struct_proces Line 902  recherche_variable_globale(struct_proces
         {          {
             case 0:              case 0:
             {              {
                 // Nous sommes en présence d'une définition et non d'une                  // La variable est une définition.
                 // variable.  
   
                 presence_variable = d_faux;                  presence_variable = d_faux;
                 break;                  break;
             }              }
Line 829  retrait_variable(struct_processus *s_eta Line 1071  retrait_variable(struct_processus *s_eta
                     .pointeur_feuille_courante;                      .pointeur_feuille_courante;
             s_arbre_courant = (*variable_a_supprimer).noeud_pere;              s_arbre_courant = (*variable_a_supprimer).noeud_pere;
             noeud_courant = (*variable_a_supprimer).noeud;              noeud_courant = (*variable_a_supprimer).noeud;
               (*s_arbre_courant).noeuds[(*noeud_courant).indice_tableau_pere]
                       = NULL;
   
             BUG((*s_arbre_courant).noeuds_utilises == 0,              BUG((*s_arbre_courant).noeuds_utilises == 0,
                     uprintf("Freed node !\n"));                      uprintf("Freed node !\n"));
Line 879  retrait_variable(struct_processus *s_eta Line 1123  retrait_variable(struct_processus *s_eta
                     .precedent = (*(*s_etat_processus)                      .precedent = (*(*s_etat_processus)
                     .pointeur_feuille_courante).precedent;                      .pointeur_feuille_courante).precedent;
   
               // Mise à jour du pointeur dans l'arbre des variables. Cette
               // mise à jour n'est nécessaire que dans le cas où la variable
               // supprimée est en tête de la liste.
   
               if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
                       .noeuds[(*(*variable_a_supprimer).noeud)
                       .indice_tableau_pere])).feuille)
               {
                   (*((*(*variable_a_supprimer).noeud_pere).noeuds
                           [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                           .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
                           .noeuds[(*(*variable_a_supprimer).noeud)
                           .indice_tableau_pere])).feuille).suivant;
               }
   
               (*s_etat_processus).pointeur_feuille_courante =
                       (*(*s_etat_processus).pointeur_feuille_courante).suivant;
               (*s_etat_processus).pointeur_variable_courante =
                       (*(*s_etat_processus).pointeur_feuille_courante).variable;
   
             noeud_courant = NULL;              noeud_courant = NULL;
         }          }
   
Line 945  retrait_variable(struct_processus *s_eta Line 1209  retrait_variable(struct_processus *s_eta
         free((*(*variable_a_supprimer).variable).nom);          free((*(*variable_a_supprimer).variable).nom);
         liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);          liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
         free((*variable_a_supprimer).variable);          free((*variable_a_supprimer).variable);
           free(variable_a_supprimer);
   
         erreur = d_absence_erreur;          erreur = d_absence_erreur;
   
         if (noeud_courant != NULL)          if (noeud_courant != NULL)
         {          {
             free((*noeud_courant).feuille);  
             free((*noeud_courant).noeuds);              free((*noeud_courant).noeuds);
             free(noeud_courant);              free(noeud_courant);
         }          }
Line 1222  liberation_arbre_variables(struct_proces Line 1486  liberation_arbre_variables(struct_proces
   
 /*  /*
 ================================================================================  ================================================================================
     Procédure renvoyant les variables dans un tableau
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bord : néant
   ================================================================================
   */
   
   int
   nombre_variables(struct_processus *s_etat_processus,
           struct_arbre_variables *l_element_courant)
   {
       int                     i;
       int                     n;
   
       struct_liste_variables  *l_variable;
   
       n = 0;
   
       if ((*l_element_courant).feuille != NULL)
       {
           l_variable = (*l_element_courant).feuille;
   
           do
           {
               n++;
               l_variable = (*l_variable).suivant;
           } while(l_variable != (*l_element_courant).feuille);
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*l_element_courant).noeuds[i] != NULL)
           {
               n += nombre_variables(s_etat_processus,
                       (*l_element_courant).noeuds[i]);
           }
       }
   
       return(n);
   }
   
   int
   liste_variables(struct_processus *s_etat_processus,
           struct_tableau_variables *tableau, int position,
           struct_arbre_variables *l_element_courant)
   {
       int                     i;
   
       struct_liste_variables  *l_variable;
   
       if ((*l_element_courant).feuille != NULL)
       {
           l_variable = (*l_element_courant).feuille;
   
           do
           {
               tableau[position].origine = (*(*l_variable).variable).origine;
               tableau[position].nom = (*(*l_variable).variable).nom;
               tableau[position].niveau = (*(*l_variable).variable).niveau;
               tableau[position].objet = (*(*l_variable).variable).objet;
               tableau[position].variable_verrouillee =
                       (*(*l_variable).variable).variable_verrouillee;
               tableau[position].variable_statique =
                       (*(*l_variable).variable).variable_statique;
               tableau[position].variable_partagee =
                       (*(*l_variable).variable).variable_partagee;
   
               position++;
               l_variable = (*l_variable).suivant;
           } while(l_variable != (*l_element_courant).feuille);
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*l_element_courant).noeuds[i] != NULL)
           {
               position = liste_variables(s_etat_processus,
                       tableau, position, (*l_element_courant).noeuds[i]);
           }
       }
   
       return(position);
   }
   
   /*
   ================================================================================
   Procédure de copie de l'arbre des variables    Procédure de copie de l'arbre des variables
 ================================================================================  ================================================================================
   Entrée :    Entrée :

Removed from v.1.32  
changed lines
  Added in v.1.33


CVSweb interface <joel.bertrand@systella.fr>