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

version 1.33, 2011/06/19 17:48:27 version 1.98, 2016/03/01 22:12:28
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.0.prerelease.0    RPL/2 (R) version 4.1.25
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2016 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 46  liste_variables_par_niveaux(struct_proce Line 46  liste_variables_par_niveaux(struct_proce
   
     struct_liste_chainee    *e;      struct_liste_chainee    *e;
   
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
     printf("  Liste des variables par niveaux\n");      printf("  Liste des variables par niveaux\n");
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
   
       if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
       {
           printf("=========================================================="
                   "======================\n");
           return;
       }
   
     printf("Backward\n");      printf("Backward\n");
     l = (*s_etat_processus).l_liste_variables_par_niveau;      l = (*s_etat_processus).l_liste_variables_par_niveau;
Line 62  liste_variables_par_niveaux(struct_proce Line 71  liste_variables_par_niveaux(struct_proce
   
         while(e != NULL)          while(e != NULL)
         {          {
             printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,              printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
                     e->donnee, ((struct_variable *) e->donnee)->niveau);                      e, e->donnee, ((struct_variable *) e->donnee)->niveau);
             e = e->suivant;              e = e->suivant;
             c++;              c++;
             if (c > 100)              if (c > 100)
Line 87  liste_variables_par_niveaux(struct_proce Line 96  liste_variables_par_niveaux(struct_proce
   
         while(e != NULL)          while(e != NULL)
         {          {
             printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,              printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
                     e->donnee, ((struct_variable *) e->donnee)->niveau);                      e, e->donnee, ((struct_variable *) e->donnee)->niveau);
             e = e->suivant;              e = e->suivant;
             c++;              c++;
             if (c > 100) exit(0);              if (c > 100) exit(0);
Line 99  liste_variables_par_niveaux(struct_proce Line 108  liste_variables_par_niveaux(struct_proce
         l = l->suivant;          l = l->suivant;
     } while(l != (*s_etat_processus).l_liste_variables_par_niveau);      } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
   
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
   
     if (fin == d_vrai) exit(0);      if (fin == d_vrai) exit(0);
   
Line 119  liste_variables_tas(struct_processus *s_ Line 129  liste_variables_tas(struct_processus *s_
   
     fin = d_faux;      fin = d_faux;
   
       if (arbre == NULL)
       {
           return;
       }
   
       printf(">>> Position :                  %d\n",
               (*arbre).indice_tableau_pere);
       printf(">>> Nombre de noeuds utilisés : %u\n",
               (*arbre).noeuds_utilises);
       printf(">>> Noeuds fils : ");
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*arbre).noeuds[i] != NULL)
           {
               printf("%d ", i);
           }
       }
   
       printf("\b\n");
   
     if ((*arbre).feuille != NULL)      if ((*arbre).feuille != NULL)
     {      {
         printf("Feuille %p\n", (*arbre).feuille);          printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
   
         printf("  Backward\n");          printf("  Backward\n");
   
Line 157  liste_variables_tas(struct_processus *s_ Line 188  liste_variables_tas(struct_processus *s_
         } while((*arbre).feuille != l);          } while((*arbre).feuille != l);
     }      }
   
       printf("----------------------------------------------------------"
               "----------------------\n");
   
     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)      for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
     {      {
         if ((*arbre).noeuds[i] != NULL)          if ((*arbre).noeuds[i] != NULL)
         {          {
   
             liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);              liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
         }          }
     }      }
Line 174  liste_variables_tas(struct_processus *s_ Line 209  liste_variables_tas(struct_processus *s_
 static void  static void
 liste_variables_par_feuilles(struct_processus *s_etat_processus)  liste_variables_par_feuilles(struct_processus *s_etat_processus)
 {  {
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
     printf("  Liste des variables sur le tas\n");      printf("  Liste des variables sur le tas\n");
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
   
     liste_variables_tas(s_etat_processus,      liste_variables_tas(s_etat_processus,
             (*s_etat_processus).s_arbre_variables);              (*s_etat_processus).s_arbre_variables);
   
     printf("===========================================================\n");      printf("=========================================================="
               "======================\n");
   
       return;
   }
   
   
   /*
   ================================================================================
     Routine de gestion du cache mémoire sur l'arbre des variables
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
   struct_arbre_variables *
   allocation_noeud(struct_processus *s_etat_processus)
   {
       struct_arbre_variables          *objet;
   
       if ((*s_etat_processus).pointeur_variables_noeud > 0)
       {
           objet = (*s_etat_processus).variables_noeud
                   [--(*s_etat_processus).pointeur_variables_noeud];
       }
       else
       {
           objet = malloc(sizeof(struct_arbre_variables));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_noeud(struct_processus *s_etat_processus,
           struct_arbre_variables *objet)
   {
       if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_noeud
                   [(*s_etat_processus).pointeur_variables_noeud++] = objet;
       }
       else
       {
           free(objet);
       }
   
       return;
   }
   
   struct_arbre_variables **
   allocation_tableau_noeuds(struct_processus *s_etat_processus)
   {
       struct_arbre_variables          **objet;
   
       if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0)
       {
           objet = (*s_etat_processus).variables_tableau_noeuds
                   [--(*s_etat_processus).pointeur_variables_tableau_noeuds];
       }
       else
       {
           objet = malloc(((size_t) (*s_etat_processus)
                   .nombre_caracteres_variables)
                   * sizeof(struct_arbre_variables *));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_tableau_noeuds(struct_processus *s_etat_processus,
           struct_arbre_variables **objet)
   {
       if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_tableau_noeuds
                   [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
                   objet;
       }
       else
       {
           free(objet);
       }
   
       return;
   }
   
   static inline struct_liste_variables *
   allocation_feuille(struct_processus *s_etat_processus)
   {
       struct_liste_variables          *objet;
   
       if ((*s_etat_processus).pointeur_variables_feuille > 0)
       {
           objet = (*s_etat_processus).variables_feuille
                   [--(*s_etat_processus).pointeur_variables_feuille];
       }
       else
       {
           objet = malloc(sizeof(struct_liste_variables));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_feuille(struct_processus *s_etat_processus,
           struct_liste_variables *objet)
   {
       if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_feuille
                   [(*s_etat_processus).pointeur_variables_feuille++] = objet;
       }
       else
       {
           free(objet);
       }
   
       return;
   }
   
   static inline struct_variable *
   allocation_variable(struct_processus *s_etat_processus)
   {
       struct_variable             *objet;
   
       if ((*s_etat_processus).pointeur_variables_variable > 0)
       {
           objet = (*s_etat_processus).variables_variable
                   [--(*s_etat_processus).pointeur_variables_variable];
       }
       else
       {
           objet = malloc(sizeof(struct_variable));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_variable(struct_processus *s_etat_processus,
           struct_variable *objet)
   {
       if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_variable
                   [(*s_etat_processus).pointeur_variables_variable++] = objet;
       }
       else
       {
           free(objet);
       }
   
     return;      return;
 }  }
Line 226  ajout_variable(struct_processus *s_etat_ Line 420  ajout_variable(struct_processus *s_etat_
     if ((*s_etat_processus).s_arbre_variables == NULL)      if ((*s_etat_processus).s_arbre_variables == NULL)
     {      {
         if (((*s_etat_processus).s_arbre_variables =          if (((*s_etat_processus).s_arbre_variables =
                 malloc(sizeof(struct_arbre_variables))) == NULL)                      allocation_noeud(s_etat_processus)) == 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);
         }          }
   
         (*(*s_etat_processus).s_arbre_variables).feuille = NULL;          (*(*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).noeuds_utilises = 0;
         (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;          (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
         (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;          (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
   
         if (((*(*s_etat_processus).s_arbre_variables).noeuds =          if (((*(*s_etat_processus).s_arbre_variables).noeuds =
                 malloc((*s_etat_processus).nombre_caracteres_variables                  allocation_tableau_noeuds(s_etat_processus)) == NULL)
                 * sizeof(struct_arbre_variables))) == 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);
Line 258  ajout_variable(struct_processus *s_etat_ Line 452  ajout_variable(struct_processus *s_etat_
     while((*ptr) != d_code_fin_chaine)      while((*ptr) != d_code_fin_chaine)
     {      {
         BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,          BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
                 printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,                  uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
                 *ptr));                  *ptr));
   
         if ((*l_variable_courante).noeuds[(*s_etat_processus)          if ((*l_variable_courante).noeuds[(*s_etat_processus)
Line 269  ajout_variable(struct_processus *s_etat_ Line 463  ajout_variable(struct_processus *s_etat_
   
             if (((*l_variable_courante).noeuds[(*s_etat_processus)              if (((*l_variable_courante).noeuds[(*s_etat_processus)
                     .pointeurs_caracteres_variables[*ptr]] =                      .pointeurs_caracteres_variables[*ptr]] =
                     malloc(sizeof(struct_arbre_variables))) == NULL)                      allocation_noeud(s_etat_processus)) == 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);
Line 284  ajout_variable(struct_processus *s_etat_ Line 478  ajout_variable(struct_processus *s_etat_
             (*(*l_variable_courante).noeuds[(*s_etat_processus)              (*(*l_variable_courante).noeuds[(*s_etat_processus)
                     .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;                      .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
             (*(*l_variable_courante).noeuds[(*s_etat_processus)              (*(*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;                      .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
   
             // Le champ noeud_pere de la structure créée pointe sur              // Le champ noeud_pere de la structure créée pointe sur
Line 306  ajout_variable(struct_processus *s_etat_ Line 503  ajout_variable(struct_processus *s_etat_
   
             if (((*(*l_variable_courante).noeuds[(*s_etat_processus)              if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
                     .pointeurs_caracteres_variables[*ptr]]).noeuds =                      .pointeurs_caracteres_variables[*ptr]]).noeuds =
                     malloc((*s_etat_processus).nombre_caracteres_variables                      allocation_tableau_noeuds(s_etat_processus)) == NULL)
                     * sizeof(struct_arbre_variables))) == 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);
Line 334  ajout_variable(struct_processus *s_etat_ Line 530  ajout_variable(struct_processus *s_etat_
         // variables de même nom. Cette liste boucle en premier lieu sur          // variables de même nom. Cette liste boucle en premier lieu sur
         // elle-même.          // elle-même.
   
         if (((*l_variable_courante).feuille = malloc(          if (((*l_variable_courante).feuille = allocation_feuille(
                 sizeof(struct_liste_variables))) == NULL)                  s_etat_processus)) == 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_variable_courante).noeuds_utilises++;
   
         (*(*l_variable_courante).feuille).suivant =          (*(*l_variable_courante).feuille).suivant =
                 (*l_variable_courante).feuille;                  (*l_variable_courante).feuille;
         (*(*l_variable_courante).feuille).precedent =          (*(*l_variable_courante).feuille).precedent =
Line 351  ajout_variable(struct_processus *s_etat_ Line 549  ajout_variable(struct_processus *s_etat_
         // Allocation de la variable sur l'élément de la liste.          // Allocation de la variable sur l'élément de la liste.
   
         if (((*(*l_variable_courante).feuille).variable =          if (((*(*l_variable_courante).feuille).variable =
                 malloc(sizeof(struct_variable))) == NULL)                  allocation_variable(s_etat_processus)) == 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);
Line 363  ajout_variable(struct_processus *s_etat_ Line 561  ajout_variable(struct_processus *s_etat_
     }      }
     else      else
     {      {
         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))          if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
                 == NULL)                  == NULL)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 380  ajout_variable(struct_processus *s_etat_ Line 578  ajout_variable(struct_processus *s_etat_
   
             BUG((*(*(*l_variable_courante).feuille).variable).niveau >=              BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
                     (*s_variable).niveau,                      (*s_variable).niveau,
                     printf("Variable=\"%s\"\n", (*s_variable).nom));                      uprintf("Variable=\"%s\"\n", (*s_variable).nom));
   
             // On ajoute la variable à la liste existante.              // On ajoute la variable à la liste existante.
   
Line 396  ajout_variable(struct_processus *s_etat_ Line 594  ajout_variable(struct_processus *s_etat_
             (*l_variable_courante).feuille = l_nouvelle_variable;              (*l_variable_courante).feuille = l_nouvelle_variable;
   
             if (((*(*l_variable_courante).feuille).variable =              if (((*(*l_variable_courante).feuille).variable =
                     malloc(sizeof(struct_variable))) == NULL)                      allocation_variable(s_etat_processus)) == 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);
Line 420  ajout_variable(struct_processus *s_etat_ Line 618  ajout_variable(struct_processus *s_etat_
   
                 BUG((*(*l_variable_candidate).variable).niveau ==                  BUG((*(*l_variable_candidate).variable).niveau ==
                         (*s_variable).niveau,                          (*s_variable).niveau,
                         printf("Variable=\"%s\"\n", (*s_variable).nom));                          uprintf("Variable=\"%s\"\n", (*s_variable).nom));
   
                 l_variable_candidate = (*l_variable_candidate).precedent;                  l_variable_candidate = (*l_variable_candidate).precedent;
             } while((l_variable_candidate != (*l_variable_courante).feuille) &&              } while((l_variable_candidate != (*l_variable_courante).feuille) &&
                     ((*(*l_variable_candidate).variable).niveau <= 1));                      ((*(*l_variable_candidate).variable).niveau <= 1));
   
               BUG((*s_variable).niveau == 0,
                       uprintf("Attempt to create a level-0 variable!\n"));
   
             if ((*(*(*(*l_variable_courante).feuille).precedent).variable)              if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
                     .niveau > 1)                      .niveau > 1)
             {              {
                 // Ajout inconditionnel des variables de niveaux 0 et 1                  // La variable précédente est de niveau strictement supérieur
                   // à 1. Il ne peut donc y avoir aucune variable de niveau
                   // inférieur ou égal à 1 puisque la boucle est triée.
                   // On insère donc directement la variable en queue.
             }              }
             else              else
             {              {
                   // Le niveau de la variable précédente dans la boucle est
                   // inférieur ou égal à 1.
                 l_variable_candidate = (*(*l_variable_courante).feuille)                  l_variable_candidate = (*(*l_variable_courante).feuille)
                         .precedent;                          .precedent;
             }              }
Line 445  ajout_variable(struct_processus *s_etat_ Line 651  ajout_variable(struct_processus *s_etat_
             (*(*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;
   
               // Si la variable suivant la variable que l'on vient d'insérer
               // dans la boucle est de niveau 0, la variable insérée est par
               // construction de niveau 1 et il convient de modifier le
               // pointeur de feuille pointant sur l'élément de plus haut niveau
               // de la boucle.
   
               if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
               {
                   (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
               }
   
             if (((*l_nouvelle_variable).variable =              if (((*l_nouvelle_variable).variable =
                     malloc(sizeof(struct_variable))) == NULL)                      allocation_variable(s_etat_processus)) == 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);
Line 465  ajout_variable(struct_processus *s_etat_ Line 682  ajout_variable(struct_processus *s_etat_
     {      {
         // Le niveau courant n'existe pas. Il est créé.          // Le niveau courant n'existe pas. Il est créé.
   
         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))          if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
                 == NULL)                  == NULL)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 481  ajout_variable(struct_processus *s_etat_ Line 698  ajout_variable(struct_processus *s_etat_
   
         // Ajout de la variable en tête de la liste          // Ajout de la variable en tête de la liste
   
         if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)          if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == 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);
Line 499  ajout_variable(struct_processus *s_etat_ Line 716  ajout_variable(struct_processus *s_etat_
     {      {
         // Le niveau courant n'existe pas. Il est créé.          // Le niveau courant n'existe pas. Il est créé.
   
         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))          if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
                 == NULL)                  == NULL)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 521  ajout_variable(struct_processus *s_etat_ Line 738  ajout_variable(struct_processus *s_etat_
   
         // Ajout de la variable en tête de la liste          // Ajout de la variable en tête de la liste
   
         if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)          if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == 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);
Line 561  ajout_variable(struct_processus *s_etat_ Line 778  ajout_variable(struct_processus *s_etat_
   
         if (niveau_acceptable == d_faux)          if (niveau_acceptable == d_faux)
         {          {
             if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))              if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
                     == NULL)                      == NULL)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 594  ajout_variable(struct_processus *s_etat_ Line 811  ajout_variable(struct_processus *s_etat_
   
         // Ajout de la variable en tête de la liste l_variable_candidate.          // Ajout de la variable en tête de la liste l_variable_candidate.
   
         if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)          if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == 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);
Line 608  ajout_variable(struct_processus *s_etat_ Line 825  ajout_variable(struct_processus *s_etat_
     {      {
         // Ajout de la variable en tête de la liste          // Ajout de la variable en tête de la liste
   
         if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)          if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == 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);
Line 772  recherche_variable(struct_processus *s_e Line 989  recherche_variable(struct_processus *s_e
   
     unsigned char               *ptr;      unsigned char               *ptr;
   
     unsigned long               niveau_appel;      integer8                    niveau_appel;
   
     if ((*s_etat_processus).s_arbre_variables == NULL)      if ((*s_etat_processus).s_arbre_variables == NULL)
     {      {
Line 976  retrait_variable(struct_processus *s_eta Line 1193  retrait_variable(struct_processus *s_eta
         unsigned char *nom_variable, unsigned char type)          unsigned char *nom_variable, unsigned char type)
 {  {
     logical1                    erreur;      logical1                    erreur;
       logical1                    variable_supprimee;
   
     struct_arbre_variables      *s_arbre_a_supprimer;      struct_arbre_variables      *s_arbre_a_supprimer;
     struct_arbre_variables      *s_arbre_courant;      struct_arbre_variables      *s_arbre_courant;
     struct_arbre_variables      *noeud_courant;  
   
     struct_liste_chainee        *l_element_courant;      struct_liste_chainee        *l_element_courant;
     struct_liste_chainee        *l_element_precedent;      struct_liste_chainee        *l_element_precedent;
Line 987  retrait_variable(struct_processus *s_eta Line 1204  retrait_variable(struct_processus *s_eta
     struct_liste_variables      *variable_a_supprimer;      struct_liste_variables      *variable_a_supprimer;
     struct_liste_variables      *variables_par_niveau;      struct_liste_variables      *variables_par_niveau;
   
     unsigned long               niveau;      integer8                    niveau;
   
       (*s_etat_processus).niveau_supprime = d_faux;
   
     if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)      if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
     {      {
Line 1069  retrait_variable(struct_processus *s_eta Line 1288  retrait_variable(struct_processus *s_eta
   
             variable_a_supprimer = (*s_etat_processus)              variable_a_supprimer = (*s_etat_processus)
                     .pointeur_feuille_courante;                      .pointeur_feuille_courante;
             s_arbre_courant = (*variable_a_supprimer).noeud_pere;              s_arbre_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"));
             (*s_arbre_courant).noeuds_utilises--;              (*s_arbre_courant).noeuds_utilises--;
   
             while((*s_arbre_courant).noeuds_utilises == 0)              (*((*(*variable_a_supprimer).noeud_pere).noeuds
                       [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                       .feuille = NULL;
   
               while(((*s_arbre_courant).noeuds_utilises == 0) &&
                       ((*s_arbre_courant).feuille_statique == NULL))
             {              {
                 s_arbre_a_supprimer = s_arbre_courant;                  s_arbre_a_supprimer = s_arbre_courant;
                 s_arbre_courant = (*s_arbre_courant).noeud_pere;                  s_arbre_courant = (*s_arbre_courant).noeud_pere;
   
                 if (s_arbre_courant == NULL)                  if (s_arbre_courant == NULL)
                 {                  {
                     free((*s_arbre_a_supprimer).noeuds);                      liberation_tableau_noeuds(s_etat_processus,
                     free(s_arbre_a_supprimer);                              (*s_arbre_a_supprimer).noeuds);
                       liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
   
                       (*s_etat_processus).s_arbre_variables = NULL;
                     break;                      break;
                 }                  }
   
Line 1100  retrait_variable(struct_processus *s_eta Line 1323  retrait_variable(struct_processus *s_eta
                 (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)                  (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
                         .indice_tableau_pere] = NULL;                          .indice_tableau_pere] = NULL;
   
                 free((*s_arbre_a_supprimer).noeuds);                  liberation_tableau_noeuds(s_etat_processus,
                 free(s_arbre_a_supprimer);                          (*s_arbre_a_supprimer).noeuds);
                   liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
   
                 BUG((*s_arbre_courant).noeuds_utilises == 0,                  BUG((*s_arbre_courant).noeuds_utilises == 0,
                         uprintf("Freed node !\n"));                          uprintf("Freed node !\n"));
Line 1142  retrait_variable(struct_processus *s_eta Line 1366  retrait_variable(struct_processus *s_eta
                     (*(*s_etat_processus).pointeur_feuille_courante).suivant;                      (*(*s_etat_processus).pointeur_feuille_courante).suivant;
             (*s_etat_processus).pointeur_variable_courante =              (*s_etat_processus).pointeur_variable_courante =
                     (*(*s_etat_processus).pointeur_feuille_courante).variable;                      (*(*s_etat_processus).pointeur_feuille_courante).variable;
   
             noeud_courant = NULL;  
         }          }
   
         // Dans tous les cas, on retire la variable de la liste des variables          // Dans tous les cas, on retire la variable de la liste des variables
Line 1151  retrait_variable(struct_processus *s_eta Line 1373  retrait_variable(struct_processus *s_eta
   
         niveau = (*(*variable_a_supprimer).variable).niveau;          niveau = (*(*variable_a_supprimer).variable).niveau;
         variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;          variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
           variable_supprimee = d_faux;
   
         if (variables_par_niveau != NULL)          if (variables_par_niveau != NULL)
         {          {
Line 1188  retrait_variable(struct_processus *s_eta Line 1411  retrait_variable(struct_processus *s_eta
                                             (*l_element_courant).suivant;                                              (*l_element_courant).suivant;
                                 }                                  }
   
                                 free(l_element_courant);                                  liberation_maillon(s_etat_processus,
                                           l_element_courant);
   
                                   if ((*variables_par_niveau).liste == NULL)
                                   {
                                       (*s_etat_processus).niveau_supprime =
                                               d_vrai;
   
                                       if ((*s_etat_processus)
                                               .l_liste_variables_par_niveau
                                               == variables_par_niveau)
                                       {
                                           // On retire l'élément de la liste
                                           // pointé par
                                           // l_liste_variable_par_niveau
   
                                           (*s_etat_processus)
                                                   .l_liste_variables_par_niveau =
                                                   (*variables_par_niveau).suivant;
                                       }
   
                                       (*(*variables_par_niveau).precedent)
                                               .suivant =
                                               (*variables_par_niveau).suivant;
                                       (*(*variables_par_niveau).suivant)
                                               .precedent =
                                               (*variables_par_niveau)
                                               .precedent;
                                       liberation_feuille(s_etat_processus,
                                               variables_par_niveau);
                                   }
   
                                   variable_supprimee = d_vrai;
                                 break;                                  break;
                             }                              }
   
Line 1198  retrait_variable(struct_processus *s_eta Line 1453  retrait_variable(struct_processus *s_eta
                     }                      }
                 }                  }
   
                   if (variable_supprimee == d_vrai)
                   {
                       break;
                   }
   
                 variables_par_niveau = (*variables_par_niveau).suivant;                  variables_par_niveau = (*variables_par_niveau).suivant;
   
             } while(variables_par_niveau != (*s_etat_processus)              } while(variables_par_niveau != (*s_etat_processus)
Line 1208  retrait_variable(struct_processus *s_eta Line 1468  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);          liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
         free(variable_a_supprimer);          liberation_feuille(s_etat_processus, variable_a_supprimer);
   
         erreur = d_absence_erreur;          erreur = d_absence_erreur;
   
         if (noeud_courant != NULL)  
         {  
             free((*noeud_courant).noeuds);  
             free(noeud_courant);  
         }  
     }      }
     else      else
     {      {
Line 1246  retrait_variable(struct_processus *s_eta Line 1500  retrait_variable(struct_processus *s_eta
 */  */
   
 logical1  logical1
 retrait_variable_par_niveau(struct_processus *s_etat_processus)  retrait_variables_par_niveau(struct_processus *s_etat_processus)
 {  {
     struct_liste_variables          *l_element_a_supprimer;      struct_liste_variables          *l_element_a_supprimer;
   
Line 1277  retrait_variable_par_niveau(struct_proce Line 1531  retrait_variable_par_niveau(struct_proce
                 break;                  break;
             }              }
   
               if (((*s_etat_processus).at_exit != NULL) &&
                       ((*s_etat_processus).niveau_courant == 0))
               {
                   // Il y a une routine ATEXIT enregistrée. On ne détruit pas
                   // les variables globales qui pourraient y être utilisées.
   
                   break;
               }
   
             while((*(*s_etat_processus).l_liste_variables_par_niveau).liste              while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
                     != NULL)                      != NULL)
             {              {
                   // Nécessaire car le pointeur sur la tête de la pile
                   // peut être modifié par retrait_variable().
                 // Sauvegarde des variables statiques.                  // Sauvegarde des variables statiques.
   
                 if ((*((struct_variable *) (*(*(*s_etat_processus)                  if ((*((struct_variable *) (*(*(*s_etat_processus)
Line 1298  retrait_variable_par_niveau(struct_proce Line 1563  retrait_variable_par_niveau(struct_proce
                                 .l_liste_variables_par_niveau).liste).donnee))                                  .l_liste_variables_par_niveau).liste).donnee))
                                 .variable_statique, ((*s_etat_processus)                                  .variable_statique, ((*s_etat_processus)
                                 .mode_execution_programme                                  .mode_execution_programme
                                  == 'Y') ? 'P' : 'E') == d_vrai)                                   == 'Y') ? 'P' : 'E') != NULL)
                         {                          {
                             (*s_etat_processus).s_liste_variables_statiques                              (*(*s_etat_processus)
                                     [(*s_etat_processus)                                      .pointeur_variable_statique_courante)
                                     .position_variable_statique_courante]                                      .objet = (*((struct_variable *)
                                     .objet = (*((struct_variable *)  
                                     (*(*(*s_etat_processus)                                      (*(*(*s_etat_processus)
                                     .l_liste_variables_par_niveau).liste)                                      .l_liste_variables_par_niveau).liste)
                                     .donnee)).objet;                                      .donnee)).objet;
Line 1337  retrait_variable_par_niveau(struct_proce Line 1601  retrait_variable_par_niveau(struct_proce
                                 .l_liste_variables_par_niveau).liste).donnee))                                  .l_liste_variables_par_niveau).liste).donnee))
                                 .variable_statique, ((*s_etat_processus)                                  .variable_statique, ((*s_etat_processus)
                                 .mode_execution_programme                                  .mode_execution_programme
                                  == 'Y') ? 'P' : 'E') == d_vrai)                                   == 'Y') ? 'P' : 'E') != NULL)
                         {                          {
                             (*s_etat_processus).s_liste_variables_statiques                              (*(*s_etat_processus)
                                     [(*s_etat_processus)                                      .pointeur_variable_statique_courante)
                                     .position_variable_statique_courante]  
                                     .objet = (*((struct_variable *)                                      .objet = (*((struct_variable *)
                                     (*(*(*s_etat_processus)                                      (*(*(*s_etat_processus)
                                     .l_liste_variables_par_niveau).liste)                                      .l_liste_variables_par_niveau).liste)
Line 1367  retrait_variable_par_niveau(struct_proce Line 1630  retrait_variable_par_niveau(struct_proce
                 {                  {
                     return(d_erreur);                      return(d_erreur);
                 }                  }
   
                   if ((*((struct_variable *) (*(*(*s_etat_processus)
                           .l_liste_variables_par_niveau).liste).donnee)).niveau
                           <= (*s_etat_processus).niveau_courant)
                   {
                       // On a retiré de l'arbre des variables toutes les
                       // variables de niveau strictement supérieur au niveau
                       // courant.
   
                       return(d_absence_erreur);
                   }
             }              }
         }          }
   
Line 1381  retrait_variable_par_niveau(struct_proce Line 1655  retrait_variable_par_niveau(struct_proce
                 .l_liste_variables_par_niveau;                  .l_liste_variables_par_niveau;
         (*s_etat_processus).l_liste_variables_par_niveau =          (*s_etat_processus).l_liste_variables_par_niveau =
                 (*l_element_a_supprimer).suivant;                  (*l_element_a_supprimer).suivant;
         free(l_element_a_supprimer);          liberation_feuille(s_etat_processus, l_element_a_supprimer);
     }      }
   
     return(d_absence_erreur);      return(d_absence_erreur);
Line 1405  void Line 1679  void
 liberation_arbre_variables(struct_processus *s_etat_processus,  liberation_arbre_variables(struct_processus *s_etat_processus,
         struct_arbre_variables *arbre, logical1 retrait_definitions)          struct_arbre_variables *arbre, logical1 retrait_definitions)
 {  {
     int                     i;      int                                 i;
   
     struct_liste_chainee    *l_element_courant_liste;      struct_liste_chainee                *l_element_courant_liste;
     struct_liste_chainee    *l_element_suivant_liste;      struct_liste_chainee                *l_element_suivant_liste;
   
     struct_liste_variables  *l_element_courant;      struct_liste_variables              *l_element_courant;
     struct_liste_variables  *l_element_suivant;      struct_liste_variables              *l_element_suivant;
   
       struct_liste_variables_statiques    *l_element_statique_courant;
       struct_liste_variables_statiques    *l_element_statique_suivant;
   
     // Libération de l'arbre des variables. Le contenu des variables n'est      // Libération de l'arbre des variables. Le contenu des variables n'est
     // pas détruit par cette opération, il sera détruit lors de la libération      // pas détruit par cette opération, il sera détruit lors de la libération
     // de la liste des variables par niveau.      // de la liste des variables par niveau.
   
       if (arbre == NULL)
       {
           return;
       }
   
     l_element_courant = (*arbre).feuille;      l_element_courant = (*arbre).feuille;
   
     if (l_element_courant != NULL)      if (l_element_courant != NULL)
Line 1424  liberation_arbre_variables(struct_proces Line 1706  liberation_arbre_variables(struct_proces
         do          do
         {          {
             l_element_suivant = (*l_element_courant).suivant;              l_element_suivant = (*l_element_courant).suivant;
             free(l_element_courant);              liberation_feuille(s_etat_processus, l_element_courant);
             l_element_courant = l_element_suivant;              l_element_courant = l_element_suivant;
         } while(l_element_courant != (*arbre).feuille);          } while(l_element_courant != (*arbre).feuille);
   
           (*arbre).feuille = NULL;
       }
   
       l_element_statique_courant = (*arbre).feuille_statique;
   
       while(l_element_statique_courant != NULL)
       {
           l_element_statique_suivant = (*l_element_statique_courant).suivant;
   
           free((*(*l_element_statique_courant).variable).nom);
           liberation(s_etat_processus, (*(*l_element_statique_courant)
                   .variable).objet);
           free((*l_element_statique_courant).variable);
           free(l_element_statique_courant);
   
           l_element_statique_courant = l_element_statique_suivant;
     }      }
   
     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)      for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
Line 1435  liberation_arbre_variables(struct_proces Line 1734  liberation_arbre_variables(struct_proces
         {          {
             liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],              liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
                     retrait_definitions);                      retrait_definitions);
               (*arbre).noeuds[i] = NULL;
         }          }
     }      }
   
Line 1460  liberation_arbre_variables(struct_proces Line 1760  liberation_arbre_variables(struct_proces
                                 (*l_element_courant_liste).donnee)).objet);                                  (*l_element_courant_liste).donnee)).objet);
                         free((*((struct_variable *) (*l_element_courant_liste)                          free((*((struct_variable *) (*l_element_courant_liste)
                                 .donnee)).nom);                                  .donnee)).nom);
                         free((*l_element_courant_liste).donnee);  
                     }                      }
   
                     l_element_suivant_liste =                      l_element_suivant_liste =
                             (*l_element_courant_liste).suivant;                              (*l_element_courant_liste).suivant;
                     free(l_element_courant_liste);                      liberation_variable(s_etat_processus, (struct_variable *)
                               (*l_element_courant_liste).donnee);
                       liberation_maillon(s_etat_processus,
                               l_element_courant_liste);
                     l_element_courant_liste = l_element_suivant_liste;                      l_element_courant_liste = l_element_suivant_liste;
                 }                  }
   
                 l_element_suivant = (*l_element_courant).suivant;                  l_element_suivant = (*l_element_courant).suivant;
                 free(l_element_courant);                  liberation_feuille(s_etat_processus, l_element_courant);
                 l_element_courant = l_element_suivant;                  l_element_courant = l_element_suivant;
             } while(l_element_courant != (*s_etat_processus)              } while(l_element_courant != (*s_etat_processus)
                     .l_liste_variables_par_niveau);                      .l_liste_variables_par_niveau);
         }          }
     }      }
   
     free((*arbre).noeuds);      liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
     free(arbre);      liberation_noeud(s_etat_processus, arbre);
       arbre = NULL;
   
     return;      return;
 }  }
Line 1496  liberation_arbre_variables(struct_proces Line 1799  liberation_arbre_variables(struct_proces
 ================================================================================  ================================================================================
 */  */
   
 int  static integer8
 nombre_variables(struct_processus *s_etat_processus,  nombre_variables_locales(struct_processus *s_etat_processus,
         struct_arbre_variables *l_element_courant)          struct_arbre_variables *l_element_courant)
 {  {
     int                     i;      integer8                            i;
     int                     n;      integer8                            n;
   
     struct_liste_variables  *l_variable;      struct_liste_variables              *l_variable;
       struct_liste_variables_statiques    *l_variable_statique;
   
       if (l_element_courant == NULL)
       {
           return(0);
       }
   
     n = 0;      n = 0;
   
Line 1518  nombre_variables(struct_processus *s_eta Line 1827  nombre_variables(struct_processus *s_eta
         } while(l_variable != (*l_element_courant).feuille);          } while(l_variable != (*l_element_courant).feuille);
     }      }
   
       if ((*l_element_courant).feuille_statique != NULL)
       {
           l_variable_statique = (*l_element_courant).feuille_statique;
   
           do
           {
               // Si le pointeur est nul, la variable est accessible et a été
               // copiée dans l'arbre des variables.
   
               if ((*(*l_variable_statique).variable).objet != NULL)
               {
                   n++;
               }
   
               l_variable_statique = (*l_variable_statique).suivant;
           } while(l_variable_statique != NULL);
       }
   
     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)      for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
     {      {
         if ((*l_element_courant).noeuds[i] != NULL)          if ((*l_element_courant).noeuds[i] != NULL)
         {          {
             n += nombre_variables(s_etat_processus,              n += nombre_variables_locales(s_etat_processus,
                     (*l_element_courant).noeuds[i]);                      (*l_element_courant).noeuds[i]);
         }          }
     }      }
Line 1530  nombre_variables(struct_processus *s_eta Line 1857  nombre_variables(struct_processus *s_eta
     return(n);      return(n);
 }  }
   
 int  
 liste_variables(struct_processus *s_etat_processus,  static integer8
         struct_tableau_variables *tableau, int position,  nombre_variables_partagees(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees *l_element_courant)
   {
       integer8                            i;
       integer8                            n;
   
       struct_liste_variables_partagees    *l_variable;
   
       if (l_element_courant == NULL)
       {
           return(0);
       }
   
       // Mutex deverrouillé par liste_variables_partagees();
       if (pthread_mutex_lock(&((*l_element_courant).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(0);
       }
   
       n = 0;
   
       if ((*l_element_courant).feuille != NULL)
       {
           l_variable = (*l_element_courant).feuille;
   
           do
           {
               n++;
               l_variable = (*l_variable).suivant;
           } while(l_variable != NULL);
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*l_element_courant).noeuds[i] != NULL)
           {
               n += nombre_variables_partagees(s_etat_processus,
                       (*l_element_courant).noeuds[i]);
           }
       }
   
       return(n);
   }
   
   
   integer8
   nombre_variables(struct_processus *s_etat_processus)
   {
       return(nombre_variables_locales(s_etat_processus,
               (*s_etat_processus).s_arbre_variables)
               + nombre_variables_partagees(s_etat_processus,
               (*(*s_etat_processus).s_arbre_variables_partagees)));
   }
   
   
   void
   liberation_mutexes_arbre_variables_partagees(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees *l_element_courant)
   {
       int                                 i;
   
       if (l_element_courant == NULL)
       {
           return;
       }
   
       if (pthread_mutex_trylock(&((*l_element_courant).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*l_element_courant).noeuds[i] != NULL)
           {
               liberation_mutexes_arbre_variables_partagees(s_etat_processus,
                       (*l_element_courant).noeuds[i]);
           }
       }
   
       return;
   }
   
   
   static integer8
   liste_variables_locales(struct_processus *s_etat_processus,
           struct_tableau_variables *tableau, integer8 position,
         struct_arbre_variables *l_element_courant)          struct_arbre_variables *l_element_courant)
 {  {
     int                     i;      integer8                            i;
   
     struct_liste_variables  *l_variable;      struct_liste_variables              *l_variable;
       struct_liste_variables_statiques    *l_variable_statique;
   
       if (l_element_courant == NULL)
       {
           return(position);
       }
   
     if ((*l_element_courant).feuille != NULL)      if ((*l_element_courant).feuille != NULL)
     {      {
Line 1555  liste_variables(struct_processus *s_etat Line 1982  liste_variables(struct_processus *s_etat
                     (*(*l_variable).variable).variable_statique;                      (*(*l_variable).variable).variable_statique;
             tableau[position].variable_partagee =              tableau[position].variable_partagee =
                     (*(*l_variable).variable).variable_partagee;                      (*(*l_variable).variable).variable_partagee;
               tableau[position].variable_masquee = d_faux;
               tableau[position].mutex = NULL;
   
             position++;              position++;
   
             l_variable = (*l_variable).suivant;              l_variable = (*l_variable).suivant;
         } while(l_variable != (*l_element_courant).feuille);          } while(l_variable != (*l_element_courant).feuille);
     }      }
   
       if ((*l_element_courant).feuille_statique != NULL)
       {
           l_variable_statique = (*l_element_courant).feuille_statique;
   
           do
           {
               if ((*(*l_variable_statique).variable).objet != NULL)
               {
                   tableau[position].origine = 'E';
                   tableau[position].nom = (*(*l_variable_statique).variable).nom;
                   tableau[position].niveau =
                           (*(*l_variable_statique).variable).niveau;
                   tableau[position].objet = (*(*l_variable_statique).variable)
                           .objet;
                   tableau[position].variable_verrouillee = d_faux;
                   tableau[position].variable_statique =
                           (*(*l_variable_statique).variable).variable_statique;
                   tableau[position].variable_partagee.pointeur = NULL;
                   tableau[position].variable_masquee = d_vrai;
                   tableau[position].mutex = NULL;
   
                   position++;
               }
   
               l_variable_statique = (*l_variable_statique).suivant;
           } while(l_variable_statique != NULL);
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*l_element_courant).noeuds[i] != NULL)
           {
               position = liste_variables_locales(s_etat_processus,
                       tableau, position, (*l_element_courant).noeuds[i]);
           }
       }
   
       return(position);
   }
   
   
   static integer8
   liste_variables_partagees(struct_processus *s_etat_processus,
           struct_tableau_variables *tableau, integer8 position,
           struct_arbre_variables_partagees *l_element_courant)
   {
       integer8                            i;
   
       struct_liste_variables_partagees    *l_variable;
   
       if (l_element_courant == NULL)
       {
           return(position);
       }
   
       if ((*l_element_courant).feuille != NULL)
       {
           l_variable = (*l_element_courant).feuille;
   
           do
           {
               tableau[position].origine = 'E';
               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 = d_faux;
               tableau[position].variable_partagee =
                       (*(*l_variable).variable).variable_partagee;
               tableau[position].variable_statique.pointeur = NULL;
               tableau[position].variable_masquee = d_faux;
               tableau[position].mutex = &((*(*l_variable).variable).mutex);
               pthread_mutex_lock(tableau[position].mutex);
   
               position++;
   
               l_variable = (*l_variable).suivant;
           } while(l_variable != NULL);
       }
   
     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)      for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
     {      {
         if ((*l_element_courant).noeuds[i] != NULL)          if ((*l_element_courant).noeuds[i] != NULL)
         {          {
             position = liste_variables(s_etat_processus,              position = liste_variables_partagees(s_etat_processus,
                     tableau, position, (*l_element_courant).noeuds[i]);                      tableau, position, (*l_element_courant).noeuds[i]);
         }          }
     }      }
   
       // Mutex verrouillé par nombre_variables_partagees();
       if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(0);
       }
   
     return(position);      return(position);
 }  }
   
   
   static int
   fonction_ordre_variables(const void *argument_1, const void *argument_2)
   {
       int                         comparaison;
   
       struct_tableau_variables    *a1;
       struct_tableau_variables    *a2;
   
       a1 = (struct_tableau_variables *) argument_1;
       a2 = (struct_tableau_variables *) argument_2;
   
       comparaison = strcmp((*a1).nom, (*a2).nom);
   
       if (comparaison != 0)
       {
           return(comparaison);
       }
       else
       {
           return(((((*a1).niveau - (*a2).niveau)) > 0) ? 1 : -1);
       }
   }
   
   
   integer8
   liste_variables(struct_processus *s_etat_processus,
           struct_tableau_variables *tableau)
   {
       integer8        nombre_elements;
   
       nombre_elements = liste_variables_locales(s_etat_processus,
               tableau, 0, (*s_etat_processus).s_arbre_variables);
       nombre_elements = liste_variables_partagees(s_etat_processus,
               tableau, nombre_elements, (*(*s_etat_processus)
               .s_arbre_variables_partagees));
   
       qsort(tableau, (size_t) nombre_elements, sizeof(struct_tableau_variables),
               fonction_ordre_variables);
   
       return(nombre_elements);
   }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Procédure de copie de l'arbre des variables    Procédure de copie de l'arbre des variables
Line 1585  liste_variables(struct_processus *s_etat Line 2145  liste_variables(struct_processus *s_etat
 ================================================================================  ================================================================================
 */  */
   
 struct_arbre_variables *  void
 copie_arbre_variables(struct_processus *s_etat_processus)  copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
           *s_nouvel_etat_processus)
 {  {
     // Les définitions sont partagées entre tous les threads et ne sont pas      // Les définitions sont partagées entre tous les threads et ne sont pas
     // copiées.      // copiées.
     //      //
     // NB : on ne copie que les variables de niveaux 0 et 1, les autres      // NB : on ne copie que les variables de niveaux 0 et 1, les autres
     // variables locales étant masquées par le processus de création de thread      // variables locales étant masquées par le processus de création de thread
     // ou de processus, elles sont inaccessibles.      // ou de processus, elles seront inaccessibles de tous les points
       // du fil d'exécution fils.
   
     BUG(1, uprintf("Oops !\n"));      // Pour copier ces variables, on récupère les variables depuis la liste par
       // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
       // structure. Les variables de niveau 0 étant non modifiables, elles
       // ne sont pas dupliquées.
   
     return(d_absence_erreur);      int                                 i;
   
       logical1                            niveau_0_traite;
       logical1                            niveau_1_traite;
   
       struct_arbre_variables              *l_variable_courante;
   
       struct_liste_chainee                *l_element_courant;
   
       struct_liste_variables              *l_niveau_courant;
       struct_liste_variables_statiques    *l_element_statique_courant;
   
       struct_variable                     s_variable;
       struct_variable_statique            s_variable_statique;
   
       unsigned char                       *ptr;
   
       (*s_nouvel_etat_processus).s_arbre_variables = NULL;
       (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
   
       l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
       
       // Si la variable en tête n'est pas une variable de niveau 0, le niveau
       // 0, s'il existe est le niveau précédent la valeur courante dans la
       // boucle.
   
       if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
               != 0)
       {
           l_niveau_courant = (*l_niveau_courant).precedent;
       }
   
       // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
       // itérations (par construction).
   
       niveau_0_traite = d_faux;
       niveau_1_traite = d_faux;
   
       for(i = 0; i <= 2; i++)
       {
           if ((*((struct_variable *) (*(*l_niveau_courant).liste)
                   .donnee)).niveau == 0)
           {
               if (niveau_0_traite == d_faux)
               {
                   l_element_courant = (*l_niveau_courant).liste;
   
                   while(l_element_courant != NULL)
                   {
                       if (ajout_variable(s_nouvel_etat_processus,
                               (struct_variable *) (*l_element_courant).donnee)
                               == d_erreur)
                       {
                           return;
                       }
   
                       l_element_courant = (*l_element_courant).suivant;
                   }
   
                   niveau_0_traite = d_vrai;
               }
           }
           else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
                   .donnee)).niveau == 1)
           {
               if (niveau_1_traite == d_faux)
               {
                   l_element_courant = (*l_niveau_courant).liste;
   
                   while(l_element_courant != NULL)
                   {
                       s_variable = (*((struct_variable *)
                               (*l_element_courant).donnee));
   
                       if ((s_variable.nom = rpl_malloc(s_nouvel_etat_processus,
                               (strlen((*((struct_variable *)
                               (*l_element_courant).donnee)).nom) + 1) *
                               sizeof(unsigned char))) == NULL)
                       {
                           (*s_nouvel_etat_processus).erreur_systeme =
                                   d_es_allocation_memoire;
                           return;
                       }
   
                       strcpy(s_variable.nom, (*((struct_variable *)
                               (*l_element_courant).donnee)).nom);
   
                       if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
                               (*((struct_variable *) (*l_element_courant).donnee))
                               .objet, 'P')) == NULL)
                       {
                           (*s_nouvel_etat_processus).erreur_systeme =
                                   d_es_allocation_memoire;
                           return;
                       }
   
                       if (ajout_variable(s_nouvel_etat_processus, &s_variable)
                               == d_erreur)
                       {
                           return;
                       }
   
                       l_element_courant = (*l_element_courant).suivant;
                   }
   
                   niveau_1_traite = d_vrai;
               }
   
               // Les variables de niveau 0 ayant déjà été copiées, on
               // peut sortir de la boucle car toutes les variables sont
               // maintenant disponibles dans le fil d'exécution fils.
   
               break;
           }
   
           l_niveau_courant = (*l_niveau_courant).precedent;
       }
   
       // Copie des variables statiques
   
       l_element_statique_courant = (*s_etat_processus)
               .l_liste_variables_statiques;
   
       while(l_element_statique_courant != NULL)
       {
           // Création des branches de l'arbre si nécessaire.
   
           if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
           {
               if (((*s_nouvel_etat_processus).s_arbre_variables =
                           allocation_noeud(s_nouvel_etat_processus)) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
               (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
                       = NULL;
               (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
               (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
                       = -1;
               (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
   
               if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
                       allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               for(i = 0; i < (*s_nouvel_etat_processus)
                       .nombre_caracteres_variables; i++)
               {
                   (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
                           = NULL;
               }
           }
   
           l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
           ptr = (*(*l_element_statique_courant).variable).nom;
   
           while((*ptr) != d_code_fin_chaine)
           {
               BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
                       [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
                       (*(*l_element_statique_courant).variable).nom, *ptr));
   
               if ((*l_variable_courante).noeuds[(*s_nouvel_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_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]] =
                           allocation_noeud(s_nouvel_etat_processus)) == NULL)
                   {
                       (*s_etat_processus).erreur_systeme =
                               d_es_allocation_memoire;
                       return;
                   }
   
                   (*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_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
                   (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).feuille_statique
                           = NULL;
                   (*(*l_variable_courante).noeuds[(*s_nouvel_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_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
                           l_variable_courante;
                   (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]])
                           .indice_tableau_pere = (*s_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr];
   
                   // Allocation du tableau noeuds[] et initialisation à zéro de
                   // tous les pointeurs.
   
                   if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).noeuds =
                           allocation_tableau_noeuds(s_nouvel_etat_processus))
                           == NULL)
                   {
                       (*s_etat_processus).erreur_systeme
                               = d_es_allocation_memoire;
                       return;
                   }
   
                   for(i = 0; i < (*s_nouvel_etat_processus)
                           .nombre_caracteres_variables; i++)
                   {
                       (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                               .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                               = NULL;
                   }
               }
   
               l_variable_courante = (*l_variable_courante).noeuds
                       [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
                       [*ptr]];
   
               ptr++;
           }
   
           // Il faut copier la variable pour la dissocier de la variable
           // restant dans le thread parent.
   
           s_variable_statique = (*(*l_element_statique_courant).variable);
   
           if (copie_objet(s_etat_processus, s_variable_statique.objet, 'P')
                   == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if ((s_variable_statique.nom = rpl_malloc(s_nouvel_etat_processus,
                   (strlen((*(*l_element_statique_courant).variable).nom) + 1) *
                   sizeof(unsigned char))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           strcpy(s_variable_statique.nom, (*(*l_element_statique_courant)
                   .variable).nom);
   
           if (creation_variable_statique(s_nouvel_etat_processus,
                   &s_variable_statique) == d_erreur)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           l_element_statique_courant = (*l_element_statique_courant).suivant;
       }
   
       return;
 }  }
   
   
Line 1614  copie_arbre_variables(struct_processus * Line 2454  copie_arbre_variables(struct_processus *
 */  */
   
 /*  /*
  * Caractères autorisés dans les instructions   * Caractères autorisés dans les variables
  *   *
  * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z   * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
  * a b c d e f g h i j k l m n o p q r s t u v w x y z   * a b c d e f g h i j k l m n o p q r s t u v w x y z
Line 1644  initialisation_variables(struct_processu Line 2484  initialisation_variables(struct_processu
     }      }
   
     if (((*s_etat_processus).pointeurs_caracteres_variables =      if (((*s_etat_processus).pointeurs_caracteres_variables =
             malloc(longueur_tableau * sizeof(int))) == NULL)              malloc(((size_t) longueur_tableau) * sizeof(int))) == NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;

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


CVSweb interface <joel.bertrand@systella.fr>