File:  [local] / rpl / src / gestion_variables.c
Revision 1.46: download - view: text, annotated - select for diffs - revision graph
Tue Aug 9 11:31:30 2011 UTC (12 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.3.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.3
    4:   Copyright (C) 1989-2011 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl-conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Fonction de debug
   29: ================================================================================
   30:   Entrée :
   31: --------------------------------------------------------------------------------
   32:   Sortie :
   33: --------------------------------------------------------------------------------
   34:   Effets de bords : néant
   35: ================================================================================
   36: */
   37: 
   38: static void
   39: liste_variables_par_niveaux(struct_processus *s_etat_processus)
   40: {
   41:     int                     c;
   42: 
   43:     logical1                fin;
   44: 
   45:     struct_liste_variables  *l;
   46: 
   47:     struct_liste_chainee    *e;
   48: 
   49:     printf("=========================================================="
   50:             "======================\n");
   51:     printf("  Liste des variables par niveaux\n");
   52:     printf("=========================================================="
   53:             "======================\n");
   54: 
   55:     if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
   56:     {
   57:         printf("=========================================================="
   58:                 "======================\n");
   59:         return;
   60:     }
   61: 
   62:     printf("Backward\n");
   63:     l = (*s_etat_processus).l_liste_variables_par_niveau;
   64:     c = 0;
   65:     fin = d_faux;
   66: 
   67:     do
   68:     {
   69:         l = l->precedent;
   70:         e = l->liste;
   71: 
   72:         while(e != NULL)
   73:         {
   74:             printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
   75:                     e, e->donnee, ((struct_variable *) e->donnee)->niveau);
   76:             e = e->suivant;
   77:             c++;
   78:             if (c > 100)
   79:             {
   80:                 fin = d_vrai;
   81:                 break;
   82:             }
   83:         }
   84: 
   85:         printf("\n");
   86: 
   87:     } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
   88: 
   89:     printf("Forward\n");
   90:     l = (*s_etat_processus).l_liste_variables_par_niveau;
   91:     c = 0;
   92: 
   93:     do
   94:     {
   95:         e = l->liste;
   96: 
   97:         while(e != NULL)
   98:         {
   99:             printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
  100:                     e, e->donnee, ((struct_variable *) e->donnee)->niveau);
  101:             e = e->suivant;
  102:             c++;
  103:             if (c > 100) exit(0);
  104:         }
  105: 
  106:         printf("\n");
  107: 
  108:         l = l->suivant;
  109:     } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
  110: 
  111:     printf("=========================================================="
  112:             "======================\n");
  113: 
  114:     if (fin == d_vrai) exit(0);
  115: 
  116:     return;
  117: }
  118: 
  119: static void
  120: liste_variables_tas(struct_processus *s_etat_processus,
  121:         struct_arbre_variables *arbre)
  122: {
  123:     int                     c;
  124:     int                     i;
  125: 
  126:     logical1                fin;
  127: 
  128:     struct_liste_variables  *l;
  129: 
  130:     fin = d_faux;
  131: 
  132:     if (arbre == NULL)
  133:     {
  134:         return;
  135:     }
  136: 
  137:     printf(">>> Position :                  %d\n",
  138:             (*arbre).indice_tableau_pere);
  139:     printf(">>> Nombre de noeuds utilisés : %u\n",
  140:             (*arbre).noeuds_utilises);
  141:     printf(">>> Noeuds fils : ");
  142: 
  143:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  144:     {
  145:         if ((*arbre).noeuds[i] != NULL)
  146:         {
  147:             printf("%d ", i);
  148:         }
  149:     }
  150: 
  151:     printf("\b\n");
  152: 
  153:     if ((*arbre).feuille != NULL)
  154:     {
  155:         printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
  156: 
  157:         printf("  Backward\n");
  158: 
  159:         l = (*arbre).feuille;
  160:         c = 0;
  161:         fin = d_faux;
  162: 
  163:         do
  164:         {
  165:             l = l->precedent;
  166:             c++;
  167:             if (c > 100)
  168:             {
  169:                 fin = d_vrai;
  170:                 break;
  171:             }
  172:             printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
  173:                     l->variable->niveau);
  174:         } while((*arbre).feuille != l);
  175: 
  176:         printf("  Forward\n");
  177: 
  178:         l = (*arbre).feuille;
  179:         c = 0;
  180: 
  181:         do
  182:         {
  183:             c++;
  184:             if (c > 100) exit(0);
  185:             printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
  186:                     l->variable->niveau);
  187:             l = l->suivant;
  188:         } while((*arbre).feuille != l);
  189:     }
  190: 
  191:     printf("----------------------------------------------------------"
  192:             "----------------------\n");
  193: 
  194:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  195:     {
  196:         if ((*arbre).noeuds[i] != NULL)
  197:         {
  198: 
  199:             liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
  200:         }
  201:     }
  202: 
  203:     if (fin == d_vrai) exit(0);
  204: 
  205:     return;
  206: }
  207: 
  208: 
  209: static void
  210: liste_variables_par_feuilles(struct_processus *s_etat_processus)
  211: {
  212:     printf("=========================================================="
  213:             "======================\n");
  214:     printf("  Liste des variables sur le tas\n");
  215:     printf("=========================================================="
  216:             "======================\n");
  217: 
  218:     liste_variables_tas(s_etat_processus,
  219:             (*s_etat_processus).s_arbre_variables);
  220: 
  221:     printf("=========================================================="
  222:             "======================\n");
  223: 
  224:     return;
  225: }
  226: 
  227: 
  228: /*
  229: ================================================================================
  230:   Routine de gestion du cache mémoire sur l'arbre des variables
  231: ================================================================================
  232:   Entrée :
  233: --------------------------------------------------------------------------------
  234:   Sortie :
  235: --------------------------------------------------------------------------------
  236:   Effets de bords : néant
  237: ================================================================================
  238: */
  239: 
  240: static inline struct_arbre_variables *
  241: allocation_noeud(struct_processus *s_etat_processus)
  242: {
  243:     struct_arbre_variables          *objet;
  244: 
  245:     if ((*s_etat_processus).pointeur_variables_noeud > 0)
  246:     {
  247:         objet = (*s_etat_processus).variables_noeud
  248:                 [--(*s_etat_processus).pointeur_variables_noeud];
  249:     }
  250:     else
  251:     {
  252:         objet = malloc(sizeof(struct_arbre_variables));
  253:     }
  254: 
  255:     return(objet);
  256: }
  257: 
  258: static inline void
  259: liberation_noeud(struct_processus *s_etat_processus,
  260:         struct_arbre_variables *objet)
  261: {
  262:     if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE)
  263:     {
  264:         (*s_etat_processus).variables_noeud
  265:                 [(*s_etat_processus).pointeur_variables_noeud++] = objet;
  266:     }
  267:     else
  268:     {
  269:         free(objet);
  270:     }
  271: 
  272:     return;
  273: }
  274: 
  275: static inline struct_arbre_variables **
  276: allocation_tableau_noeuds(struct_processus *s_etat_processus)
  277: {
  278:     struct_arbre_variables          **objet;
  279: 
  280:     if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0)
  281:     {
  282:         objet = (*s_etat_processus).variables_tableau_noeuds
  283:                 [--(*s_etat_processus).pointeur_variables_tableau_noeuds];
  284:     }
  285:     else
  286:     {
  287:         objet = malloc((*s_etat_processus).nombre_caracteres_variables
  288:                 * sizeof(struct_arbre_variables *));
  289:     }
  290: 
  291:     return(objet);
  292: }
  293: 
  294: static inline void
  295: liberation_tableau_noeuds(struct_processus *s_etat_processus,
  296:         struct_arbre_variables **objet)
  297: {
  298:     if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
  299:     {
  300:         (*s_etat_processus).variables_tableau_noeuds
  301:                 [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
  302:                 objet;
  303:     }
  304:     else
  305:     {
  306:         free(objet);
  307:     }
  308: 
  309:     return;
  310: }
  311: 
  312: static inline struct_liste_variables *
  313: allocation_feuille(struct_processus *s_etat_processus)
  314: {
  315:     struct_liste_variables          *objet;
  316: 
  317:     if ((*s_etat_processus).pointeur_variables_feuille > 0)
  318:     {
  319:         objet = (*s_etat_processus).variables_feuille
  320:                 [--(*s_etat_processus).pointeur_variables_feuille];
  321:     }
  322:     else
  323:     {
  324:         objet = malloc(sizeof(struct_liste_variables));
  325:     }
  326: 
  327:     return(objet);
  328: }
  329: 
  330: static inline void
  331: liberation_feuille(struct_processus *s_etat_processus,
  332:         struct_liste_variables *objet)
  333: {
  334:     if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
  335:     {
  336:         (*s_etat_processus).variables_feuille
  337:                 [(*s_etat_processus).pointeur_variables_feuille++] = objet;
  338:     }
  339:     else
  340:     {
  341:         free(objet);
  342:     }
  343: 
  344:     return;
  345: }
  346: 
  347: static inline struct_variable *
  348: allocation_variable(struct_processus *s_etat_processus)
  349: {
  350:     struct_variable             *objet;
  351: 
  352:     if ((*s_etat_processus).pointeur_variables_variable > 0)
  353:     {
  354:         objet = (*s_etat_processus).variables_variable
  355:                 [--(*s_etat_processus).pointeur_variables_variable];
  356:     }
  357:     else
  358:     {
  359:         objet = malloc(sizeof(struct_variable));
  360:     }
  361: 
  362:     return(objet);
  363: }
  364: 
  365: static inline void
  366: liberation_variable(struct_processus *s_etat_processus,
  367:         struct_variable *objet)
  368: {
  369:     if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
  370:     {
  371:         (*s_etat_processus).variables_variable
  372:                 [(*s_etat_processus).pointeur_variables_variable++] = objet;
  373:     }
  374:     else
  375:     {
  376:         free(objet);
  377:     }
  378: 
  379:     return;
  380: }
  381: 
  382: 
  383: /*
  384: ================================================================================
  385:   Routine de création d'une nouvelle variable
  386: ================================================================================
  387:   Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
  388:   dans le cas 'v', la variable est volatile.
  389:   dans le cas 's', elle est statique.
  390:   Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
  391:   dans le cas 'p', la variable est privée.
  392:   dans le cas 's', elle est partagée.
  393: --------------------------------------------------------------------------------
  394:   Sortie :
  395: --------------------------------------------------------------------------------
  396:   Effets de bords : néant
  397: ================================================================================
  398: */
  399: 
  400: static logical1
  401: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
  402: {
  403:     int                         i;
  404: 
  405:     logical1                    niveau_acceptable;
  406: 
  407:     struct_liste_variables      *l_nouvelle_variable;
  408:     struct_liste_variables      *l_variable_candidate;
  409: 
  410:     struct_arbre_variables      *l_variable_courante;
  411:     struct_arbre_variables      *l_variable_precedente;
  412: 
  413:     struct_liste_chainee        *l_nouvel_element;
  414: 
  415:     unsigned char               *ptr;
  416: 
  417:     void                        *pointeur_variable_cree;
  418: 
  419:     if ((*s_etat_processus).s_arbre_variables == NULL)
  420:     {
  421:         if (((*s_etat_processus).s_arbre_variables =
  422:                     allocation_noeud(s_etat_processus)) == NULL)
  423:         {
  424:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  425:             return(d_erreur);
  426:         }
  427: 
  428:         (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
  429:         (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
  430:         (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
  431:         (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
  432: 
  433:         if (((*(*s_etat_processus).s_arbre_variables).noeuds =
  434:                     allocation_tableau_noeuds(s_etat_processus)) == NULL)
  435:         {
  436:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  437:             return(d_erreur);
  438:         }
  439: 
  440:         for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  441:         {
  442:             (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
  443:         }
  444:     }
  445: 
  446:     l_variable_precedente = NULL;
  447:     l_variable_courante = (*s_etat_processus).s_arbre_variables;
  448:     ptr = (*s_variable).nom;
  449: 
  450:     while((*ptr) != d_code_fin_chaine)
  451:     {
  452:         BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
  453:                 uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
  454:                 *ptr));
  455: 
  456:         if ((*l_variable_courante).noeuds[(*s_etat_processus)
  457:                 .pointeurs_caracteres_variables[*ptr]] == NULL)
  458:         {
  459:             // Le noeud n'existe pas encore, on le crée et on le marque
  460:             // comme utilisé dans la structure parente.
  461: 
  462:             if (((*l_variable_courante).noeuds[(*s_etat_processus)
  463:                     .pointeurs_caracteres_variables[*ptr]] =
  464:                     allocation_noeud(s_etat_processus)) == NULL)
  465:             {
  466:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  467:                 return(d_erreur);
  468:             }
  469: 
  470:             (*l_variable_courante).noeuds_utilises++;
  471: 
  472:             // La feuille est par défaut vide et aucun élément du tableau noeuds
  473:             // (les branches qui peuvent être issues de ce nouveau noeud)
  474:             // n'est encore utilisée.
  475: 
  476:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  477:                     .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
  478:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  479:                     .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
  480: 
  481:             // Le champ noeud_pere de la structure créée pointe sur
  482:             // la structure parente et l'indice tableau_pere correspond à la
  483:             // position réelle dans le tableau noeuds[] de la structure parente
  484:             // du noeud courant. Cette valeur sera utilisée lors de la
  485:             // destruction du noeud pour annuler le pointeur contenu dans
  486:             // le tableau noeuds[] de la structure parente.
  487: 
  488:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  489:                     .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
  490:                     l_variable_courante;
  491:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  492:                     .pointeurs_caracteres_variables[*ptr]])
  493:                     .indice_tableau_pere = (*s_etat_processus)
  494:                     .pointeurs_caracteres_variables[*ptr];
  495: 
  496:             // Allocation du tableau noeuds[] et initialisation à zéro de
  497:             // tous les pointeurs.
  498: 
  499:             if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
  500:                     .pointeurs_caracteres_variables[*ptr]]).noeuds =
  501:                     allocation_tableau_noeuds(s_etat_processus)) == NULL)
  502:             {
  503:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  504:                 return(d_erreur);
  505:             }
  506: 
  507:             for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  508:             {
  509:                 (*(*l_variable_courante).noeuds[(*s_etat_processus)
  510:                         .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
  511:                         = NULL;
  512:             }
  513:         }
  514: 
  515:         l_variable_precedente = l_variable_courante;
  516:         l_variable_courante = (*l_variable_courante).noeuds
  517:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
  518:         ptr++;
  519:     }
  520: 
  521:     if ((*l_variable_courante).feuille == NULL)
  522:     {
  523:         // Aucune variable de même nom préexiste. On alloue le premier
  524:         // élément de la liste doublement chaînée contenant toutes les
  525:         // variables de même nom. Cette liste boucle en premier lieu sur
  526:         // elle-même.
  527: 
  528:         if (((*l_variable_courante).feuille = allocation_feuille(
  529:                 s_etat_processus)) == NULL)
  530:         {
  531:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  532:             return(d_erreur);
  533:         }
  534: 
  535:         (*l_variable_courante).noeuds_utilises++;
  536: 
  537:         (*(*l_variable_courante).feuille).suivant =
  538:                 (*l_variable_courante).feuille;
  539:         (*(*l_variable_courante).feuille).precedent =
  540:                 (*l_variable_courante).feuille;
  541:         (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
  542:         (*(*l_variable_courante).feuille).noeud = l_variable_courante;
  543: 
  544:         // Allocation de la variable sur l'élément de la liste.
  545: 
  546:         if (((*(*l_variable_courante).feuille).variable =
  547:                 allocation_variable(s_etat_processus)) == NULL)
  548:         { 
  549:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  550:             return(d_erreur);
  551:         }
  552: 
  553:         (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
  554:                 (*s_variable);
  555:         pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
  556:     }
  557:     else
  558:     {
  559:         if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
  560:                 == NULL)
  561:         {
  562:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  563:             return(d_erreur);
  564:         }
  565: 
  566:         if ((*s_variable).niveau > 1)
  567:         {
  568:             // Cas d'une variable locale
  569: 
  570:             // Si le niveau de la dernière variable de même nom est
  571:             // supérieur au niveau de la variable locale que l'on veut
  572:             // enregistrer dans la liste, cette liste est incohérente.
  573: 
  574:             BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
  575:                     (*s_variable).niveau,
  576:                     uprintf("Variable=\"%s\"\n", (*s_variable).nom));
  577: 
  578:             // On ajoute la variable à la liste existante.
  579: 
  580:             (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
  581:             (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
  582:                     .precedent;
  583:             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
  584:             (*l_nouvelle_variable).noeud = l_variable_courante;
  585:             (*(*(*l_variable_courante).feuille).precedent).suivant =
  586:                     l_nouvelle_variable;
  587:             (*(*l_variable_courante).feuille).precedent =
  588:                     l_nouvelle_variable;
  589:             (*l_variable_courante).feuille = l_nouvelle_variable;
  590: 
  591:             if (((*(*l_variable_courante).feuille).variable =
  592:                     allocation_variable(s_etat_processus)) == NULL)
  593:             { 
  594:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  595:                 return(d_erreur);
  596:             }
  597: 
  598:             (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
  599:                     = (*s_variable);
  600:             pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
  601:         }
  602:         else
  603:         {
  604:             // Cas d'une variable globale (niveau 0 [définitions] ou 1
  605:             // [variables globales])
  606: 
  607:             l_variable_candidate = (*l_variable_courante).feuille;
  608: 
  609:             do
  610:             {
  611:                 // S'il y a déjà une variable de même niveau, la pile
  612:                 // est incohérente.
  613: 
  614:                 BUG((*(*l_variable_candidate).variable).niveau ==
  615:                         (*s_variable).niveau,
  616:                         uprintf("Variable=\"%s\"\n", (*s_variable).nom));
  617: 
  618:                 l_variable_candidate = (*l_variable_candidate).precedent;
  619:             } while((l_variable_candidate != (*l_variable_courante).feuille) &&
  620:                     ((*(*l_variable_candidate).variable).niveau <= 1));
  621: 
  622:             BUG((*s_variable).niveau == 0,
  623:                     uprintf("Attempt to create a level-0 variable!\n"));
  624: 
  625:             if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
  626:                     .niveau > 1)
  627:             {
  628:                 // La variable précédente est de niveau strictement supérieur
  629:                 // à 1. Il ne peut donc y avoir aucune variable de niveau
  630:                 // inférieur ou égal à 1 puisque la boucle est triée.
  631:                 // On insère donc directement la variable en queue.
  632:             }
  633:             else
  634:             {
  635:                 // Le niveau de la variable précédente dans la boucle est
  636:                 // inférieur ou égal à 1.
  637:                 l_variable_candidate = (*(*l_variable_courante).feuille)
  638:                         .precedent;
  639:             }
  640: 
  641:             (*l_nouvelle_variable).suivant = l_variable_candidate;
  642:             (*l_nouvelle_variable).precedent = (*l_variable_candidate)
  643:                     .precedent;
  644:             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
  645:             (*l_nouvelle_variable).noeud = l_variable_courante;
  646:             (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
  647:             (*l_variable_candidate).precedent = l_nouvelle_variable;
  648: 
  649:             // Si la variable suivant la variable que l'on vient d'insérer
  650:             // dans la boucle est de niveau 0, la variable insérée est par
  651:             // construction de niveau 1 et il convient de modifier le
  652:             // pointeur de feuille pointant sur l'élément de plus haut niveau
  653:             // de la boucle.
  654: 
  655:             if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
  656:             {
  657:                 (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
  658:             }
  659: 
  660:             if (((*l_nouvelle_variable).variable =
  661:                     allocation_variable(s_etat_processus)) == NULL)
  662:             { 
  663:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  664:                 return(d_erreur);
  665:             }
  666: 
  667:             (*(*l_nouvelle_variable).variable) = (*s_variable);
  668:             pointeur_variable_cree = (*l_nouvelle_variable).variable;
  669:         }
  670:     }
  671: 
  672:     // Ajout de la variable nouvellement créée à la liste par niveaux.
  673:     // Le pointeur contenu dans la structure de description du processus indique
  674:     // toujours le plus haut niveau utilisé.
  675: 
  676:     if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
  677:     {
  678:         // Le niveau courant n'existe pas. Il est créé.
  679: 
  680:         if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
  681:                 == NULL)
  682:         {
  683:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  684:             return(d_erreur);
  685:         }
  686: 
  687:         (*l_nouvelle_variable).suivant = l_nouvelle_variable;
  688:         (*l_nouvelle_variable).precedent = l_nouvelle_variable;
  689:         (*l_nouvelle_variable).noeud_pere = NULL;
  690:         (*l_nouvelle_variable).liste = NULL;
  691: 
  692:         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
  693: 
  694:         // Ajout de la variable en tête de la liste
  695: 
  696:         if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
  697:         {
  698:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  699:             return(d_erreur);
  700:         }
  701: 
  702:         (*l_nouvel_element).suivant = (*(*s_etat_processus)
  703:                 .l_liste_variables_par_niveau).liste;
  704:         (*l_nouvel_element).donnee = pointeur_variable_cree;
  705:         (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
  706:                 l_nouvel_element;
  707:     }
  708:     else if ((*s_variable).niveau > (*((struct_variable *)
  709:             (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
  710:             .donnee)).niveau)
  711:     {
  712:         // Le niveau courant n'existe pas. Il est créé.
  713: 
  714:         if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
  715:                 == NULL)
  716:         {
  717:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  718:             return(d_erreur);
  719:         }
  720: 
  721:         (*l_nouvelle_variable).suivant = (*s_etat_processus)
  722:                 .l_liste_variables_par_niveau;
  723:         (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
  724:                 .l_liste_variables_par_niveau).precedent;
  725:         (*l_nouvelle_variable).noeud_pere = NULL;
  726:         (*l_nouvelle_variable).liste = NULL;
  727:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
  728:                 .suivant = l_nouvelle_variable;
  729:         (*(*s_etat_processus).l_liste_variables_par_niveau)
  730:                 .precedent = l_nouvelle_variable;
  731: 
  732:         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
  733: 
  734:         // Ajout de la variable en tête de la liste
  735: 
  736:         if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
  737:         {
  738:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  739:             return(d_erreur);
  740:         }
  741: 
  742:         (*l_nouvel_element).suivant = (*(*s_etat_processus)
  743:                 .l_liste_variables_par_niveau).liste;
  744:         (*l_nouvel_element).donnee = pointeur_variable_cree;
  745:         (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
  746:                 l_nouvel_element;
  747:     }
  748:     else if ((*s_variable).niveau <= 1)
  749:     {
  750:         // Création d'une variable de niveau 0 ou 1. Il convient de
  751:         // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
  752:         // regarde la position courante et les deux précédentes.
  753: 
  754:         l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
  755:         niveau_acceptable = d_faux;
  756: 
  757:         for(i = 0; i <= 2; i++)
  758:         {
  759:             if ((*l_variable_candidate).liste == NULL)
  760:             {
  761:                 continue;
  762:             }
  763: 
  764:             if ((*((struct_variable *) (*(*l_variable_candidate)
  765:                     .liste).donnee)).niveau == (*s_variable).niveau)
  766:             {
  767:                 niveau_acceptable = d_vrai;
  768:                 break;
  769:             }
  770: 
  771:             l_variable_candidate = (*l_variable_candidate).precedent;
  772:         }
  773: 
  774:         if (niveau_acceptable == d_faux)
  775:         {
  776:             if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
  777:                     == NULL)
  778:             {
  779:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  780:                 return(d_erreur);
  781:             }
  782: 
  783:             l_variable_candidate =
  784:                     (*(*s_etat_processus).l_liste_variables_par_niveau)
  785:                     .precedent;
  786: 
  787:             // On ne peut créer qu'une variable de niveau supérieur ou égal à
  788:             // 1 lors de l'exécution normale d'un programme. Les variables
  789:             // de niveau 0 sont créées à l'initialisation et relèvent du
  790:             // cas précédent car il n'existe lors de leur création aucun
  791:             // niveau non nul.
  792: 
  793:             BUG((*s_variable).niveau == 0,
  794:                     uprintf("Attempt to create a level-0 variable!\n"));
  795: 
  796:             (*l_nouvelle_variable).suivant = l_variable_candidate;
  797:             (*l_nouvelle_variable).precedent = (*l_variable_candidate)
  798:                     .precedent;
  799:             (*l_nouvelle_variable).noeud_pere = NULL;
  800:             (*l_nouvelle_variable).liste = NULL;
  801:             (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
  802:             (*l_variable_candidate).precedent = l_nouvelle_variable;
  803: 
  804:             l_variable_candidate = l_nouvelle_variable;
  805:         }
  806: 
  807:         // Ajout de la variable en tête de la liste l_variable_candidate.
  808: 
  809:         if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
  810:         {
  811:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  812:             return(d_erreur);
  813:         }
  814: 
  815:         (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
  816:         (*l_nouvel_element).donnee = pointeur_variable_cree;
  817:         (*l_variable_candidate).liste = l_nouvel_element;
  818:     }
  819:     else
  820:     {
  821:         // Ajout de la variable en tête de la liste
  822: 
  823:         if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
  824:         {
  825:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  826:             return(d_erreur);
  827:         }
  828: 
  829:         (*l_nouvel_element).suivant = (*(*s_etat_processus)
  830:                 .l_liste_variables_par_niveau).liste;
  831:         (*l_nouvel_element).donnee = pointeur_variable_cree;
  832:         (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
  833:                 l_nouvel_element;
  834:     }
  835: 
  836:     return(d_absence_erreur);
  837: }
  838: 
  839: 
  840: logical1
  841: creation_variable(struct_processus *s_etat_processus,
  842:         struct_variable *s_variable,
  843:         unsigned char autorisation_creation_variable_statique,
  844:         unsigned char autorisation_creation_variable_partagee)
  845: {
  846:     if ((*s_etat_processus).mode_execution_programme == 'Y')
  847:     {
  848:         (*s_variable).origine = 'P';
  849:     }
  850:     else
  851:     {
  852:         (*s_variable).origine = 'E';
  853:     }
  854: 
  855:     if ((*s_variable).niveau == 0)
  856:     {
  857:         // Un point d'entrée de définition est verrouillé.
  858: 
  859:         if ((*s_variable).origine == 'P')
  860:         {
  861:             (*s_variable).variable_statique.adresse = 0;
  862:             (*s_variable).variable_partagee.adresse = 0;
  863:         }
  864:         else
  865:         {
  866:             (*s_variable).variable_statique.pointeur = NULL;
  867:             (*s_variable).variable_partagee.pointeur = NULL;
  868:         }
  869: 
  870:         (*s_variable).variable_verrouillee = d_vrai;
  871:     }
  872:     else if ((*s_variable).niveau == 1)
  873:     {
  874:         // Une variable globale ne peut être statique.
  875: 
  876:         if ((*s_variable).origine == 'P')
  877:         {
  878:             (*s_variable).variable_statique.adresse = 0;
  879:             (*s_variable).variable_partagee.adresse = 0;
  880:         }
  881:         else
  882:         {
  883:             (*s_variable).variable_statique.pointeur = NULL;
  884:             (*s_variable).variable_partagee.pointeur = NULL;
  885:         }
  886: 
  887:         (*s_variable).variable_verrouillee = d_faux;
  888:     }
  889:     else
  890:     {
  891:         // 0 -> variable volatile
  892:         // adresse de création -> variable statique
  893: 
  894:         if (autorisation_creation_variable_statique == 'V')
  895:         {
  896:             if (autorisation_creation_variable_partagee == 'S')
  897:             {
  898:                 // On force la création d'une variable partagée
  899: 
  900:                 if ((*s_variable).origine == 'P')
  901:                 {
  902:                     (*s_variable).variable_statique.adresse = 0;
  903:                     (*s_variable).variable_partagee.adresse =
  904:                             (*s_etat_processus).position_courante;
  905:                 }
  906:                 else
  907:                 {
  908:                     (*s_variable).variable_statique.pointeur = NULL;
  909:                     (*s_variable).variable_partagee.pointeur =
  910:                             (*s_etat_processus).objet_courant;
  911:                 }
  912:             }
  913:             else
  914:             {
  915:                 // On force la création d'une variable volatile
  916: 
  917:                 if ((*s_variable).origine == 'P')
  918:                 {
  919:                     (*s_variable).variable_statique.adresse = 0;
  920:                     (*s_variable).variable_partagee.adresse = 0;
  921:                 }
  922:                 else
  923:                 {
  924:                     (*s_variable).variable_statique.pointeur = NULL;
  925:                     (*s_variable).variable_partagee.pointeur = NULL;
  926:                 }
  927:             }
  928:         }
  929:         else
  930:         {
  931:             // On force la création d'une variable statique.
  932: 
  933:             if ((*s_variable).origine == 'P')
  934:             {
  935:                 (*s_variable).variable_statique.adresse =
  936:                         (*s_etat_processus).position_courante;
  937:                 (*s_variable).variable_partagee.adresse = 0;
  938:             }
  939:             else
  940:             {
  941:                 (*s_variable).variable_statique.pointeur =
  942:                         (*s_etat_processus).objet_courant;
  943:                 (*s_variable).variable_partagee.pointeur = 0;
  944:             }
  945:         }
  946: 
  947:         (*s_variable).variable_verrouillee = d_faux;
  948:     }
  949: 
  950:     /*
  951:      * Recherche de la feuille correspondante dans l'arbre des variables.
  952:      * Si cette feuille n'existe pas, elle est créée.
  953:      */
  954: 
  955:     if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
  956:     {
  957:         return(d_erreur);
  958:     }
  959: 
  960:     return(d_absence_erreur);
  961: }
  962: 
  963: 
  964: /*
  965: ================================================================================
  966:   Procédure de recherche d'une variable par son nom dans la base
  967: ================================================================================
  968:   Entrée :
  969: --------------------------------------------------------------------------------
  970:   Sortie :
  971: --------------------------------------------------------------------------------
  972:   Effets de bord : néant
  973: ================================================================================
  974: */
  975: 
  976: logical1
  977: recherche_variable(struct_processus *s_etat_processus,
  978:         unsigned char *nom_variable)
  979: {
  980:     int                         pointeur;
  981: 
  982:     struct_arbre_variables      *l_variable_courante;
  983:     struct_liste_pile_systeme   *l_element_courant;
  984: 
  985:     unsigned char               *ptr;
  986: 
  987:     unsigned long               niveau_appel;
  988: 
  989:     if ((*s_etat_processus).s_arbre_variables == NULL)
  990:     {
  991:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  992:         return(d_faux);
  993:     }
  994: 
  995:     l_variable_courante = (*s_etat_processus).s_arbre_variables;
  996:     ptr = nom_variable;
  997: 
  998:     while((*ptr) != d_code_fin_chaine)
  999:     {
 1000:         pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
 1001: 
 1002:         if (pointeur < 0)
 1003:         {
 1004:             // Caractère hors de l'alphabet des variables
 1005: 
 1006:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
 1007:             return(d_faux);
 1008:         }
 1009: 
 1010:         if ((*l_variable_courante).noeuds[pointeur] == NULL)
 1011:         {
 1012:             // Le chemin de la variable candidate n'existe pas.
 1013:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
 1014:             return(d_faux);
 1015:         }
 1016: 
 1017:         l_variable_courante = (*l_variable_courante).noeuds[pointeur];
 1018:         ptr++;
 1019:     }
 1020: 
 1021:     if ((*l_variable_courante).feuille != NULL)
 1022:     {
 1023:         // Il existe une pile de variables de même nom. Le sommet de la
 1024:         // pile est la variable de niveau le plus haut.
 1025: 
 1026:         l_element_courant = (*s_etat_processus).l_base_pile_systeme;
 1027: 
 1028:         if (l_element_courant == NULL)
 1029:         {
 1030:             // Problème : la pile système est vide !
 1031:             (*s_etat_processus).erreur_systeme = d_es_pile_vide;
 1032:             return(d_faux);
 1033:         }
 1034: 
 1035:         while((*l_element_courant).retour_definition != 'Y')
 1036:         {
 1037:             l_element_courant = (*l_element_courant).suivant;
 1038: 
 1039:             if (l_element_courant == NULL)
 1040:             {
 1041:                 (*s_etat_processus).erreur_systeme = d_es_pile_vide;
 1042:                 return(d_faux);
 1043:             }
 1044:         }
 1045: 
 1046:         niveau_appel = (*l_element_courant).niveau_courant;
 1047: 
 1048:         if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
 1049:         {
 1050:             // Une variable locale est accessible puisque créée dans la
 1051:             // fonction courante.
 1052: 
 1053:             (*s_etat_processus).pointeur_variable_courante =
 1054:                     (*(*l_variable_courante).feuille).variable;
 1055:             (*s_etat_processus).pointeur_feuille_courante =
 1056:                     (*l_variable_courante).feuille;
 1057:             return(d_vrai);
 1058:         }
 1059:         else
 1060:         {
 1061:             // Aucune variable locale n'est accessible depuis la fonction.
 1062:             // Dans ce cas, on prend la variable de niveau le plus bas
 1063:             // si ce niveau est inférieur ou égal à 1 (variable globale
 1064:             // ou fonction définie par l'utilisateur). Si le niveau de la
 1065:             // plus ancienne variable est strictement supérieur à 1, il
 1066:             // s'agit d'une variable locale inaccessible.
 1067: 
 1068:             if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
 1069:                     .niveau <= 1)
 1070:             {
 1071:                 (*s_etat_processus).pointeur_variable_courante =
 1072:                         (*(*(*l_variable_courante).feuille).precedent).variable;
 1073:                 (*s_etat_processus).pointeur_feuille_courante =
 1074:                         (*(*l_variable_courante).feuille).precedent;
 1075: 
 1076:                 // S'il existe une variable de niveau 0 et une seconde de
 1077:                 // niveau 1, la variable de niveau 0 (fonction) est masquée
 1078:                 // par celle de niveau 1.
 1079: 
 1080:                 if (((*(*(*(*l_variable_courante).feuille).precedent)
 1081:                         .variable).niveau == 0) && ((*(*(*(*
 1082:                         (*l_variable_courante).feuille).precedent).precedent)
 1083:                         .variable).niveau == 1))
 1084:                 {
 1085:                     (*s_etat_processus).pointeur_variable_courante =
 1086:                             (*(*(*(*l_variable_courante).feuille).precedent)
 1087:                             .precedent).variable;
 1088:                     (*s_etat_processus).pointeur_feuille_courante =
 1089:                             (*(*(*l_variable_courante).feuille).precedent)
 1090:                             .precedent;
 1091:                 }
 1092: 
 1093:                 return(d_vrai);
 1094:             }
 1095:         }
 1096:     }
 1097: 
 1098:     (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
 1099:     return(d_faux);
 1100: }
 1101: 
 1102: 
 1103: logical1
 1104: recherche_variable_globale(struct_processus *s_etat_processus,
 1105:         unsigned char *nom)
 1106: {
 1107:     logical1            presence_variable;
 1108: 
 1109:     presence_variable = recherche_variable(s_etat_processus, nom);
 1110: 
 1111:     if (presence_variable == d_vrai)
 1112:     {
 1113:         switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
 1114:         {
 1115:             case 0:
 1116:             {
 1117:                 // La variable est une définition.
 1118:                 presence_variable = d_faux;
 1119:                 break;
 1120:             }
 1121: 
 1122:             case 1:
 1123:             {
 1124:                 break;
 1125:             }
 1126: 
 1127:             default:
 1128:             {
 1129:                 if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
 1130:                         .precedent).variable).niveau == 1)
 1131:                 {
 1132:                     (*s_etat_processus).pointeur_feuille_courante =
 1133:                             (*(*s_etat_processus).pointeur_feuille_courante)
 1134:                             .precedent;
 1135:                     (*s_etat_processus).pointeur_variable_courante =
 1136:                             (*(*s_etat_processus).pointeur_feuille_courante)
 1137:                             .variable;
 1138:                 }
 1139:                 else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
 1140:                         .precedent).precedent).variable).niveau == 1)
 1141:                 {
 1142:                     (*s_etat_processus).pointeur_feuille_courante =
 1143:                             (*(*(*s_etat_processus).pointeur_feuille_courante)
 1144:                             .precedent).precedent;
 1145:                     (*s_etat_processus).pointeur_variable_courante =
 1146:                             (*(*s_etat_processus).pointeur_feuille_courante)
 1147:                             .variable;
 1148:                 }
 1149:                 else
 1150:                 {
 1151:                     presence_variable = d_faux;
 1152:                 }
 1153: 
 1154:                 break;
 1155:             }
 1156:         }
 1157:     }
 1158: 
 1159:     if (presence_variable == d_vrai)
 1160:     {
 1161:         if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
 1162:         {
 1163:             // La variable n'est pas globale, elle est partagée.
 1164:             presence_variable = d_faux;
 1165:             (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
 1166:         }
 1167:     }
 1168: 
 1169:     return(presence_variable);
 1170: }
 1171: 
 1172: 
 1173: /*
 1174: ================================================================================
 1175:   Procédure de retrait d'une variable de la base
 1176: ================================================================================
 1177:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
 1178:            les globales) ou strictement globale.
 1179: --------------------------------------------------------------------------------
 1180:   Sortie :
 1181: --------------------------------------------------------------------------------
 1182:   Effets de bord : néant
 1183: ================================================================================
 1184: */
 1185: 
 1186: logical1
 1187: retrait_variable(struct_processus *s_etat_processus,
 1188:         unsigned char *nom_variable, unsigned char type)
 1189: {
 1190:     logical1                    erreur;
 1191:     logical1                    variable_supprimee;
 1192: 
 1193:     struct_arbre_variables      *s_arbre_a_supprimer;
 1194:     struct_arbre_variables      *s_arbre_courant;
 1195: 
 1196:     struct_liste_chainee        *l_element_courant;
 1197:     struct_liste_chainee        *l_element_precedent;
 1198: 
 1199:     struct_liste_variables      *variable_a_supprimer;
 1200:     struct_liste_variables      *variables_par_niveau;
 1201: 
 1202:     unsigned long               niveau;
 1203: 
 1204:     (*s_etat_processus).niveau_supprime = d_faux;
 1205: 
 1206:     if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
 1207:     {
 1208:         // Une variable correspondant au nom recherché est accessible.
 1209: 
 1210:         if (type == 'G')
 1211:         {
 1212:             if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
 1213:             {
 1214:                 // La variable obtenue est une variable locale. il faut
 1215:                 // s'assurer qu'il existe une variable de niveau 1 de même
 1216:                 // nom sur la feuille.
 1217: 
 1218:                 if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
 1219:                         .precedent).variable).niveau <= 1)
 1220:                 {
 1221:                     (*s_etat_processus).pointeur_feuille_courante =
 1222:                             (*(*s_etat_processus).pointeur_feuille_courante)
 1223:                             .precedent;
 1224:                     (*s_etat_processus).pointeur_variable_courante =
 1225:                             (*(*s_etat_processus).pointeur_feuille_courante)
 1226:                             .variable;
 1227: 
 1228:                     // Si la variable retournée est de niveau 0, on regarde
 1229:                     // un peu plus loin si une variable de niveau 1 existe.
 1230: 
 1231:                     if (((*(*(*s_etat_processus).pointeur_feuille_courante)
 1232:                             .variable).niveau == 0) &&
 1233:                             ((*(*(*(*s_etat_processus)
 1234:                             .pointeur_feuille_courante).precedent).variable)
 1235:                             .niveau == 1))
 1236:                     {
 1237:                         (*s_etat_processus).pointeur_feuille_courante =
 1238:                                 (*(*s_etat_processus).pointeur_feuille_courante)
 1239:                                 .precedent;
 1240:                         (*s_etat_processus).pointeur_variable_courante =
 1241:                                 (*(*s_etat_processus).pointeur_feuille_courante)
 1242:                                 .variable;
 1243:                     }
 1244:                 }
 1245:                 else
 1246:                 {
 1247:                     // Aucune variable globale (niveau 1) n'existe.
 1248: 
 1249:                     erreur = d_erreur;
 1250:                     (*s_etat_processus).erreur_execution =
 1251:                             d_ex_variable_non_definie;
 1252:                     return(erreur);
 1253:                 }
 1254:             }
 1255: 
 1256:             if ((*(*s_etat_processus).pointeur_variable_courante)
 1257:                     .variable_verrouillee == d_vrai)
 1258:             {
 1259:                 erreur = d_erreur;
 1260:                 (*s_etat_processus).erreur_execution =
 1261:                         d_ex_variable_verrouillee;
 1262:                 return(erreur);
 1263:             }
 1264:         }
 1265: 
 1266:         // Suppression de la variable de la liste.
 1267:         // Deux cas peuvent survenir :
 1268:         // 1/ les pointeurs sur la variable et la variable suivante
 1269:         // sont identiques et on supprime la variable ainsi que la feuille
 1270:         // associée ;
 1271:         // 2/ ces deux pointeurs sont différents et se contente de retirer
 1272:         // la structure décrivant la variable.
 1273: 
 1274:         if ((*s_etat_processus).pointeur_feuille_courante ==
 1275:                 (*(*s_etat_processus).pointeur_feuille_courante).suivant)
 1276:         {
 1277:             // Cas 1 :
 1278:             // On retire la variable du noeud en décrémentant le nombre
 1279:             // de feuilles de ce noeud. Si le nombre de feuilles du noeud
 1280:             // est nul, on retire les noeuds récursivement jusqu'à obtenir
 1281:             // un nombre non nul de feuilles utilisées (ou la racine des
 1282:             // variables).
 1283: 
 1284:             variable_a_supprimer = (*s_etat_processus)
 1285:                     .pointeur_feuille_courante;
 1286:             s_arbre_courant = (*variable_a_supprimer).noeud;
 1287:             BUG((*s_arbre_courant).noeuds_utilises == 0,
 1288:                     uprintf("Freed node !\n"));
 1289:             (*s_arbre_courant).noeuds_utilises--;
 1290: 
 1291:             (*((*(*variable_a_supprimer).noeud_pere).noeuds
 1292:                     [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
 1293:                     .feuille = NULL;
 1294: 
 1295:             while((*s_arbre_courant).noeuds_utilises == 0)
 1296:             {
 1297:                 s_arbre_a_supprimer = s_arbre_courant;
 1298:                 s_arbre_courant = (*s_arbre_courant).noeud_pere;
 1299: 
 1300:                 if (s_arbre_courant == NULL)
 1301:                 {
 1302:                     liberation_tableau_noeuds(s_etat_processus,
 1303:                             (*s_arbre_a_supprimer).noeuds);
 1304:                     liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
 1305: 
 1306:                     (*s_etat_processus).s_arbre_variables = NULL;
 1307:                     break;
 1308:                 }
 1309: 
 1310:                 // s_arbre_a_supprimer contient la structure de feuille qui
 1311:                 // vient d'être libérée. Il s'agit maintenant
 1312:                 // d'annuler le pointeur dans le tableau noeuds de la structure
 1313:                 // pointée par noeud_pere, soit s_arbre_courant.
 1314: 
 1315:                 BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
 1316:                         uprintf("Invalid pointer !\n"));
 1317:                 (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
 1318:                         .indice_tableau_pere] = NULL;
 1319: 
 1320:                 liberation_tableau_noeuds(s_etat_processus,
 1321:                         (*s_arbre_a_supprimer).noeuds);
 1322:                 liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
 1323: 
 1324:                 BUG((*s_arbre_courant).noeuds_utilises == 0,
 1325:                         uprintf("Freed node !\n"));
 1326:                 (*s_arbre_courant).noeuds_utilises--;
 1327:             }
 1328:         }
 1329:         else
 1330:         {
 1331:             // Cas 2 :
 1332:             // On retire la variable de la liste.
 1333: 
 1334:             variable_a_supprimer = (*s_etat_processus)
 1335:                     .pointeur_feuille_courante;
 1336: 
 1337:             (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
 1338:                     .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
 1339:                     .suivant;
 1340:             (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
 1341:                     .precedent = (*(*s_etat_processus)
 1342:                     .pointeur_feuille_courante).precedent;
 1343: 
 1344:             // Mise à jour du pointeur dans l'arbre des variables. Cette
 1345:             // mise à jour n'est nécessaire que dans le cas où la variable
 1346:             // supprimée est en tête de la liste.
 1347: 
 1348:             if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
 1349:                     .noeuds[(*(*variable_a_supprimer).noeud)
 1350:                     .indice_tableau_pere])).feuille)
 1351:             {
 1352:                 (*((*(*variable_a_supprimer).noeud_pere).noeuds
 1353:                         [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
 1354:                         .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
 1355:                         .noeuds[(*(*variable_a_supprimer).noeud)
 1356:                         .indice_tableau_pere])).feuille).suivant;
 1357:             }
 1358: 
 1359:             (*s_etat_processus).pointeur_feuille_courante =
 1360:                     (*(*s_etat_processus).pointeur_feuille_courante).suivant;
 1361:             (*s_etat_processus).pointeur_variable_courante =
 1362:                     (*(*s_etat_processus).pointeur_feuille_courante).variable;
 1363:         }
 1364: 
 1365:         // Dans tous les cas, on retire la variable de la liste des variables
 1366:         // par niveau.
 1367: 
 1368:         niveau = (*(*variable_a_supprimer).variable).niveau;
 1369:         variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
 1370:         variable_supprimee = d_faux;
 1371: 
 1372:         if (variables_par_niveau != NULL)
 1373:         {
 1374:             do
 1375:             {
 1376:                 l_element_courant = (*variables_par_niveau).liste;
 1377: 
 1378:                 if (l_element_courant != NULL)
 1379:                 {
 1380:                     if ((*((struct_variable *) (*l_element_courant).donnee))
 1381:                             .niveau == niveau)
 1382:                     {
 1383:                         // On parcourt le bon niveau.
 1384: 
 1385:                         l_element_precedent = NULL;
 1386: 
 1387:                         while(l_element_courant != NULL)
 1388:                         {
 1389:                             // Tant que l_element_courant est non nul, il reste
 1390:                             // des variables à explorer dans le niveau courant.
 1391: 
 1392:                             if ((*l_element_courant).donnee ==
 1393:                                     (void *) (*variable_a_supprimer).variable)
 1394:                             {
 1395:                                 // On a trouvé la variable à supprimer.
 1396: 
 1397:                                 if (l_element_precedent == NULL)
 1398:                                 {
 1399:                                     (*variables_par_niveau).liste =
 1400:                                             (*l_element_courant).suivant;
 1401:                                 }
 1402:                                 else
 1403:                                 {
 1404:                                     (*l_element_precedent).suivant =
 1405:                                             (*l_element_courant).suivant;
 1406:                                 }
 1407: 
 1408:                                 liberation_maillon(s_etat_processus,
 1409:                                         l_element_courant);
 1410: 
 1411:                                 if ((*variables_par_niveau).liste == NULL)
 1412:                                 {
 1413:                                     (*s_etat_processus).niveau_supprime =
 1414:                                             d_vrai;
 1415: 
 1416:                                     if ((*s_etat_processus)
 1417:                                             .l_liste_variables_par_niveau
 1418:                                             == variables_par_niveau)
 1419:                                     {
 1420:                                         // On retire l'élément de la liste
 1421:                                         // pointé par
 1422:                                         // l_liste_variable_par_niveau
 1423: 
 1424:                                         (*s_etat_processus)
 1425:                                                 .l_liste_variables_par_niveau =
 1426:                                                 (*variables_par_niveau).suivant;
 1427:                                     }
 1428: 
 1429:                                     (*(*variables_par_niveau).precedent)
 1430:                                             .suivant =
 1431:                                             (*variables_par_niveau).suivant;
 1432:                                     (*(*variables_par_niveau).suivant)
 1433:                                             .precedent =
 1434:                                             (*variables_par_niveau)
 1435:                                             .precedent;
 1436:                                     liberation_feuille(s_etat_processus,
 1437:                                             variables_par_niveau);
 1438:                                 }
 1439: 
 1440:                                 variable_supprimee = d_vrai;
 1441:                                 break;
 1442:                             }
 1443: 
 1444:                             l_element_precedent = l_element_courant;
 1445:                             l_element_courant = (*l_element_courant).suivant;
 1446:                         }
 1447:                     }
 1448:                 }
 1449: 
 1450:                 if (variable_supprimee == d_vrai)
 1451:                 {
 1452:                     break;
 1453:                 }
 1454: 
 1455:                 variables_par_niveau = (*variables_par_niveau).suivant;
 1456: 
 1457:             } while(variables_par_niveau != (*s_etat_processus)
 1458:                     .l_liste_variables_par_niveau);
 1459:         }
 1460: 
 1461:         // Puis on libère le contenu de la variable.
 1462: 
 1463:         free((*(*variable_a_supprimer).variable).nom);
 1464:         liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
 1465:         liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
 1466:         liberation_feuille(s_etat_processus, variable_a_supprimer);
 1467: 
 1468:         erreur = d_absence_erreur;
 1469:     }
 1470:     else
 1471:     {
 1472:         // Aucune variable n'est accessible depuis le point courant du
 1473:         // programme.
 1474: 
 1475:         erreur = d_erreur;
 1476:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
 1477:     }
 1478: 
 1479:     return(erreur);
 1480: }
 1481: 
 1482: 
 1483: /*
 1484: ================================================================================
 1485:   Procédure de retrait des variables de niveau strictement supérieur au
 1486:   niveau courant
 1487: ================================================================================
 1488:   Entrée :
 1489: --------------------------------------------------------------------------------
 1490:   Sortie :
 1491: --------------------------------------------------------------------------------
 1492:   Effets de bord : néant
 1493: ================================================================================
 1494: */
 1495: 
 1496: logical1
 1497: retrait_variable_par_niveau(struct_processus *s_etat_processus)
 1498: {
 1499:     struct_liste_variables          *l_element_a_supprimer;
 1500: 
 1501:     // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
 1502:     // La tête de la pile contient toujours les variables de plus haut niveau
 1503:     // créées.
 1504: 
 1505:     while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
 1506:     {
 1507:         if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
 1508:         {
 1509:             // Si le niveau ne contient aucune variable, on le détruit.
 1510:             // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
 1511:             // faire.
 1512:         }
 1513:         else
 1514:         {
 1515:             // Le niveau contient des variables.
 1516: 
 1517:             if ((*((struct_variable *) (*(*(*s_etat_processus)
 1518:                     .l_liste_variables_par_niveau).liste).donnee)).niveau
 1519:                     <= (*s_etat_processus).niveau_courant)
 1520:             {
 1521:                 // On a retiré de l'arbre des variables toutes les
 1522:                 // variables de niveau strictement supérieur au niveau
 1523:                 // courant.
 1524: 
 1525:                 break;
 1526:             }
 1527: 
 1528:             while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
 1529:                     != NULL)
 1530:             {
 1531:                 // Nécessaire car le pointeur sur la tête de la pile
 1532:                 // peut être modifié par retrait_variable().
 1533:                 // Sauvegarde des variables statiques.
 1534: 
 1535:                 if ((*((struct_variable *) (*(*(*s_etat_processus)
 1536:                         .l_liste_variables_par_niveau).liste).donnee)).origine
 1537:                         == 'P')
 1538:                 {
 1539:                     if ((*((struct_variable *) (*(*(*s_etat_processus)
 1540:                             .l_liste_variables_par_niveau).liste).donnee))
 1541:                             .variable_statique.adresse != 0)
 1542:                     {
 1543:                         if (recherche_variable_statique(s_etat_processus,
 1544:                                 (*((struct_variable *) (*(*(*s_etat_processus)
 1545:                                 .l_liste_variables_par_niveau).liste).donnee))
 1546:                                 .nom, (*((struct_variable *)
 1547:                                 (*(*(*s_etat_processus)
 1548:                                 .l_liste_variables_par_niveau).liste).donnee))
 1549:                                 .variable_statique, ((*s_etat_processus)
 1550:                                 .mode_execution_programme
 1551:                                  == 'Y') ? 'P' : 'E') == d_vrai)
 1552:                         {
 1553:                             (*s_etat_processus).s_liste_variables_statiques
 1554:                                     [(*s_etat_processus)
 1555:                                     .position_variable_statique_courante]
 1556:                                     .objet = (*((struct_variable *)
 1557:                                     (*(*(*s_etat_processus)
 1558:                                     .l_liste_variables_par_niveau).liste)
 1559:                                     .donnee)).objet;
 1560:                         }
 1561:                         else
 1562:                         {
 1563:                             (*s_etat_processus).erreur_systeme =
 1564:                                     d_es_variable_introuvable;
 1565:                         }
 1566: 
 1567:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1568:                                 .l_liste_variables_par_niveau).liste).donnee))
 1569:                                 .objet = NULL;
 1570:                     }
 1571:                 }
 1572:                 else
 1573:                 {
 1574:                     if ((*((struct_variable *) (*(*(*s_etat_processus)
 1575:                             .l_liste_variables_par_niveau).liste).donnee))
 1576:                             .variable_statique.pointeur != NULL)
 1577:                     {
 1578:                         /*
 1579:                          * Gestion des variables statiques
 1580:                          */
 1581: 
 1582:                         if (recherche_variable_statique(s_etat_processus,
 1583:                                 (*((struct_variable *) (*(*(*s_etat_processus)
 1584:                                 .l_liste_variables_par_niveau).liste).donnee))
 1585:                                 .nom, (*((struct_variable *)
 1586:                                 (*(*(*s_etat_processus)
 1587:                                 .l_liste_variables_par_niveau).liste).donnee))
 1588:                                 .variable_statique, ((*s_etat_processus)
 1589:                                 .mode_execution_programme
 1590:                                  == 'Y') ? 'P' : 'E') == d_vrai)
 1591:                         {
 1592:                             (*s_etat_processus).s_liste_variables_statiques
 1593:                                     [(*s_etat_processus)
 1594:                                     .position_variable_statique_courante]
 1595:                                     .objet = (*((struct_variable *)
 1596:                                     (*(*(*s_etat_processus)
 1597:                                     .l_liste_variables_par_niveau).liste)
 1598:                                     .donnee)).objet;
 1599:                         }
 1600:                         else
 1601:                         {
 1602:                             (*s_etat_processus).erreur_systeme =
 1603:                                     d_es_variable_introuvable;
 1604:                             return(d_erreur);
 1605:                         }
 1606: 
 1607:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1608:                                 .l_liste_variables_par_niveau).liste).donnee))
 1609:                                 .objet = NULL;
 1610:                     }
 1611:                 }
 1612: 
 1613:                 if (retrait_variable(s_etat_processus,
 1614:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1615:                         .l_liste_variables_par_niveau).liste).donnee)).nom,
 1616:                         'L') == d_erreur)
 1617:                 {
 1618:                     return(d_erreur);
 1619:                 }
 1620: 
 1621:                 if ((*((struct_variable *) (*(*(*s_etat_processus)
 1622:                         .l_liste_variables_par_niveau).liste).donnee)).niveau
 1623:                         <= (*s_etat_processus).niveau_courant)
 1624:                 {
 1625:                     // On a retiré de l'arbre des variables toutes les
 1626:                     // variables de niveau strictement supérieur au niveau
 1627:                     // courant.
 1628: 
 1629:                     return(d_absence_erreur);
 1630:                 }
 1631:             }
 1632:         }
 1633: 
 1634:         // On retire l'élément de la liste doublement chaînée et circulaire.
 1635: 
 1636:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
 1637:                 = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
 1638:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
 1639:                 = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
 1640: 
 1641:         l_element_a_supprimer = (*s_etat_processus)
 1642:                 .l_liste_variables_par_niveau;
 1643:         (*s_etat_processus).l_liste_variables_par_niveau =
 1644:                 (*l_element_a_supprimer).suivant;
 1645:         liberation_feuille(s_etat_processus, l_element_a_supprimer);
 1646:     }
 1647: 
 1648:     return(d_absence_erreur);
 1649: }
 1650: 
 1651: 
 1652: /*
 1653: ================================================================================
 1654:   Procédure de retrait des toutes les variables locales et globales
 1655: ================================================================================
 1656:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
 1657:            de niveau 0)
 1658: --------------------------------------------------------------------------------
 1659:   Sortie :
 1660: --------------------------------------------------------------------------------
 1661:   Effets de bord : néant
 1662: ================================================================================
 1663: */
 1664: 
 1665: void
 1666: liberation_arbre_variables(struct_processus *s_etat_processus,
 1667:         struct_arbre_variables *arbre, logical1 retrait_definitions)
 1668: {
 1669:     int                     i;
 1670: 
 1671:     struct_liste_chainee    *l_element_courant_liste;
 1672:     struct_liste_chainee    *l_element_suivant_liste;
 1673: 
 1674:     struct_liste_variables  *l_element_courant;
 1675:     struct_liste_variables  *l_element_suivant;
 1676: 
 1677:     // Libération de l'arbre des variables. Le contenu des variables n'est
 1678:     // pas détruit par cette opération, il sera détruit lors de la libération
 1679:     // de la liste des variables par niveau.
 1680: 
 1681:     if (arbre == NULL)
 1682:     {
 1683:         return;
 1684:     }
 1685: 
 1686:     l_element_courant = (*arbre).feuille;
 1687: 
 1688:     if (l_element_courant != NULL)
 1689:     {
 1690:         do
 1691:         {
 1692:             l_element_suivant = (*l_element_courant).suivant;
 1693:             liberation_feuille(s_etat_processus, l_element_courant);
 1694:             l_element_courant = l_element_suivant;
 1695:         } while(l_element_courant != (*arbre).feuille);
 1696: 
 1697:         (*arbre).feuille = NULL;
 1698:     }
 1699: 
 1700:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
 1701:     {
 1702:         if ((*arbre).noeuds[i] != NULL)
 1703:         {
 1704:             liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
 1705:                     retrait_definitions);
 1706:             (*arbre).noeuds[i] = NULL;
 1707:         }
 1708:     }
 1709: 
 1710:     // Suppression de la liste des variables par niveau.
 1711: 
 1712:     if (arbre == (*s_etat_processus).s_arbre_variables)
 1713:     {
 1714:         l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
 1715: 
 1716:         if (l_element_courant != NULL)
 1717:         {
 1718:             do
 1719:             {
 1720:                 l_element_courant_liste = (*l_element_courant).liste;
 1721: 
 1722:                 while(l_element_courant_liste != NULL)
 1723:                 {
 1724:                     if ((retrait_definitions == d_vrai) ||
 1725:                             ((*((struct_variable *) (*l_element_courant_liste)
 1726:                             .donnee)).niveau >= 1))
 1727:                     {
 1728:                         liberation(s_etat_processus, (*((struct_variable *)
 1729:                                 (*l_element_courant_liste).donnee)).objet);
 1730:                         free((*((struct_variable *) (*l_element_courant_liste)
 1731:                                 .donnee)).nom);
 1732:                     }
 1733: 
 1734:                     l_element_suivant_liste =
 1735:                             (*l_element_courant_liste).suivant;
 1736:                     liberation_variable(s_etat_processus, (struct_variable *)
 1737:                             (*l_element_courant_liste).donnee);
 1738:                     liberation_maillon(s_etat_processus,
 1739:                             l_element_courant_liste);
 1740:                     l_element_courant_liste = l_element_suivant_liste;
 1741:                 }
 1742: 
 1743:                 l_element_suivant = (*l_element_courant).suivant;
 1744:                 liberation_feuille(s_etat_processus, l_element_courant);
 1745:                 l_element_courant = l_element_suivant;
 1746:             } while(l_element_courant != (*s_etat_processus)
 1747:                     .l_liste_variables_par_niveau);
 1748:         }
 1749:     }
 1750: 
 1751:     liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
 1752:     liberation_noeud(s_etat_processus, arbre);
 1753:     arbre = NULL;
 1754: 
 1755:     return;
 1756: }
 1757: 
 1758: 
 1759: /*
 1760: ================================================================================
 1761:   Procédure renvoyant les variables dans un tableau
 1762: ================================================================================
 1763:   Entrée :
 1764: --------------------------------------------------------------------------------
 1765:   Sortie :
 1766: --------------------------------------------------------------------------------
 1767:   Effets de bord : néant
 1768: ================================================================================
 1769: */
 1770: 
 1771: int
 1772: nombre_variables(struct_processus *s_etat_processus,
 1773:         struct_arbre_variables *l_element_courant)
 1774: {
 1775:     int                     i;
 1776:     int                     n;
 1777: 
 1778:     struct_liste_variables  *l_variable;
 1779: 
 1780:     n = 0;
 1781: 
 1782:     if ((*l_element_courant).feuille != NULL)
 1783:     {
 1784:         l_variable = (*l_element_courant).feuille;
 1785: 
 1786:         do
 1787:         {
 1788:             n++;
 1789:             l_variable = (*l_variable).suivant;
 1790:         } while(l_variable != (*l_element_courant).feuille);
 1791:     }
 1792: 
 1793:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
 1794:     {
 1795:         if ((*l_element_courant).noeuds[i] != NULL)
 1796:         {
 1797:             n += nombre_variables(s_etat_processus,
 1798:                     (*l_element_courant).noeuds[i]);
 1799:         }
 1800:     }
 1801: 
 1802:     return(n);
 1803: }
 1804: 
 1805: int
 1806: liste_variables(struct_processus *s_etat_processus,
 1807:         struct_tableau_variables *tableau, int position,
 1808:         struct_arbre_variables *l_element_courant)
 1809: {
 1810:     int                     i;
 1811: 
 1812:     struct_liste_variables  *l_variable;
 1813: 
 1814:     if ((*l_element_courant).feuille != NULL)
 1815:     {
 1816:         l_variable = (*l_element_courant).feuille;
 1817: 
 1818:         do
 1819:         {
 1820:             tableau[position].origine = (*(*l_variable).variable).origine;
 1821:             tableau[position].nom = (*(*l_variable).variable).nom;
 1822:             tableau[position].niveau = (*(*l_variable).variable).niveau;
 1823:             tableau[position].objet = (*(*l_variable).variable).objet;
 1824:             tableau[position].variable_verrouillee =
 1825:                     (*(*l_variable).variable).variable_verrouillee;
 1826:             tableau[position].variable_statique =
 1827:                     (*(*l_variable).variable).variable_statique;
 1828:             tableau[position].variable_partagee =
 1829:                     (*(*l_variable).variable).variable_partagee;
 1830: 
 1831:             position++;
 1832:             l_variable = (*l_variable).suivant;
 1833:         } while(l_variable != (*l_element_courant).feuille);
 1834:     }
 1835: 
 1836:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
 1837:     {
 1838:         if ((*l_element_courant).noeuds[i] != NULL)
 1839:         {
 1840:             position = liste_variables(s_etat_processus,
 1841:                     tableau, position, (*l_element_courant).noeuds[i]);
 1842:         }
 1843:     }
 1844: 
 1845:     return(position);
 1846: }
 1847: 
 1848: /*
 1849: ================================================================================
 1850:   Procédure de copie de l'arbre des variables
 1851: ================================================================================
 1852:   Entrée :
 1853: --------------------------------------------------------------------------------
 1854:   Sortie :
 1855: --------------------------------------------------------------------------------
 1856:   Effets de bord : néant
 1857: ================================================================================
 1858: */
 1859: 
 1860: void
 1861: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
 1862:         *s_nouvel_etat_processus)
 1863: {
 1864:     // Les définitions sont partagées entre tous les threads et ne sont pas
 1865:     // copiées.
 1866:     //
 1867:     // NB : on ne copie que les variables de niveaux 0 et 1, les autres
 1868:     // variables locales étant masquées par le processus de création de thread
 1869:     // ou de processus, elles seront inaccessibles de tous les points
 1870:     // du fil d'exécution fils.
 1871: 
 1872:     // Pour copier ces variables, on récupère les variables depuis la liste par
 1873:     // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
 1874:     // structure. Les variables de niveau 0 étant non modifiables, elles
 1875:     // ne sont pas dupliquées.
 1876: 
 1877:     int                             i;
 1878: 
 1879:     struct_liste_chainee            *l_element_courant;
 1880: 
 1881:     struct_liste_variables          *l_niveau_courant;
 1882: 
 1883:     struct_variable                 s_variable;
 1884: 
 1885:     (*s_nouvel_etat_processus).s_arbre_variables = NULL;
 1886:     (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
 1887: 
 1888:     l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
 1889:     
 1890:     // Si la variable en tête n'est pas une variable de niveau 0, le niveau
 1891:     // 0, s'il existe est le nivau précédent la valeur courante dans la
 1892:     // boucle.
 1893: 
 1894:     if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
 1895:             != 0)
 1896:     {
 1897:         l_niveau_courant = (*l_niveau_courant).precedent;
 1898:     }
 1899: 
 1900:     // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
 1901:     // itérations (par construction).
 1902: 
 1903:     for(i = 0; i <= 2; i++)
 1904:     {
 1905:         if ((*((struct_variable *) (*(*l_niveau_courant).liste)
 1906:                 .donnee)).niveau == 0)
 1907:         {
 1908:             l_element_courant = (*l_niveau_courant).liste;
 1909: 
 1910:             while(l_element_courant != NULL)
 1911:             {
 1912:                 if (ajout_variable(s_nouvel_etat_processus,
 1913:                         (struct_variable *) (*l_element_courant).donnee)
 1914:                         == d_erreur)
 1915:                 {
 1916:                     return;
 1917:                 }
 1918: 
 1919:                 l_element_courant = (*l_element_courant).suivant;
 1920:             }
 1921:         }
 1922:         else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
 1923:                 .donnee)).niveau == 1)
 1924:         {
 1925:             l_element_courant = (*l_niveau_courant).liste;
 1926: 
 1927:             while(l_element_courant != NULL)
 1928:             {
 1929:                 s_variable = (*((struct_variable *)
 1930:                         (*l_element_courant).donnee));
 1931: 
 1932:                 if ((s_variable.nom = strdup((*((struct_variable *)
 1933:                         (*l_element_courant).donnee)).nom)) == NULL)
 1934:                 {
 1935:                     (*s_nouvel_etat_processus).erreur_systeme =
 1936:                             d_es_allocation_memoire;
 1937:                     return;
 1938:                 }
 1939: 
 1940:                 if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
 1941:                         (*((struct_variable *) (*l_element_courant).donnee))
 1942:                         .objet, 'P')) == NULL)
 1943:                 {
 1944:                     (*s_nouvel_etat_processus).erreur_systeme =
 1945:                             d_es_allocation_memoire;
 1946:                     return;
 1947:                 }
 1948: 
 1949:                 if (ajout_variable(s_nouvel_etat_processus, &s_variable)
 1950:                         == d_erreur)
 1951:                 {
 1952:                     return;
 1953:                 }
 1954: 
 1955:                 l_element_courant = (*l_element_courant).suivant;
 1956:             }
 1957: 
 1958:             // Les variables de niveau 0 ayant déjà été copiées, on
 1959:             // peut sortir de la boucle car toutes les variables sont
 1960:             // maintenant disponibles dans le fil d'exécution fils.
 1961: 
 1962:             break;
 1963:         }
 1964: 
 1965:         l_niveau_courant = (*l_niveau_courant).precedent;
 1966:     }
 1967: 
 1968:     return;
 1969: }
 1970: 
 1971: 
 1972: /*
 1973: ================================================================================
 1974:   Procédure d'initialisation de la table de correspondance des variables
 1975: ================================================================================
 1976:   Entrée :
 1977: --------------------------------------------------------------------------------
 1978:   Sortie :
 1979: --------------------------------------------------------------------------------
 1980:   Effets de bord : néant
 1981: ================================================================================
 1982: */
 1983: 
 1984: /*
 1985:  * Caractères autorisés dans les instructions
 1986:  *
 1987:  * 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
 1988:  * 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
 1989:  * _
 1990:  * 1 2 3 4 5 6 7 8 9 0
 1991:  */
 1992: 
 1993: void
 1994: initialisation_variables(struct_processus *s_etat_processus)
 1995: {
 1996:     int             decalage;
 1997:     int             i;
 1998:     int             longueur_tableau;
 1999: 
 2000:     unsigned char   caractere;
 2001: 
 2002:     // Récupération de la longueur d'un unsigned char
 2003: 
 2004:     longueur_tableau = 1;
 2005:     decalage = 0;
 2006:     caractere = 1;
 2007: 
 2008:     while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
 2009:     {
 2010:         decalage++;
 2011:         longueur_tableau *= 2;
 2012:     }
 2013: 
 2014:     if (((*s_etat_processus).pointeurs_caracteres_variables =
 2015:             malloc(longueur_tableau * sizeof(int))) == NULL)
 2016:     {
 2017:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2018:         return;
 2019:     }
 2020: 
 2021:     for(i = 0; i < longueur_tableau; i++)
 2022:     {
 2023:         (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
 2024:     }
 2025: 
 2026:     (*s_etat_processus).nombre_caracteres_variables = 0;
 2027: 
 2028: #define DECLARATION_CARACTERE(c) \
 2029:         do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
 2030:         (*s_etat_processus).nombre_caracteres_variables++; } while(0)
 2031: 
 2032:     DECLARATION_CARACTERE('A');
 2033:     DECLARATION_CARACTERE('B');
 2034:     DECLARATION_CARACTERE('C');
 2035:     DECLARATION_CARACTERE('D');
 2036:     DECLARATION_CARACTERE('E');
 2037:     DECLARATION_CARACTERE('F');
 2038:     DECLARATION_CARACTERE('G');
 2039:     DECLARATION_CARACTERE('H');
 2040:     DECLARATION_CARACTERE('I');
 2041:     DECLARATION_CARACTERE('J');
 2042:     DECLARATION_CARACTERE('K');
 2043:     DECLARATION_CARACTERE('L');
 2044:     DECLARATION_CARACTERE('M');
 2045:     DECLARATION_CARACTERE('N');
 2046:     DECLARATION_CARACTERE('O');
 2047:     DECLARATION_CARACTERE('P');
 2048:     DECLARATION_CARACTERE('Q');
 2049:     DECLARATION_CARACTERE('R');
 2050:     DECLARATION_CARACTERE('S');
 2051:     DECLARATION_CARACTERE('T');
 2052:     DECLARATION_CARACTERE('U');
 2053:     DECLARATION_CARACTERE('V');
 2054:     DECLARATION_CARACTERE('W');
 2055:     DECLARATION_CARACTERE('X');
 2056:     DECLARATION_CARACTERE('Y');
 2057:     DECLARATION_CARACTERE('Z');
 2058: 
 2059:     DECLARATION_CARACTERE('a');
 2060:     DECLARATION_CARACTERE('b');
 2061:     DECLARATION_CARACTERE('c');
 2062:     DECLARATION_CARACTERE('d');
 2063:     DECLARATION_CARACTERE('e');
 2064:     DECLARATION_CARACTERE('f');
 2065:     DECLARATION_CARACTERE('g');
 2066:     DECLARATION_CARACTERE('h');
 2067:     DECLARATION_CARACTERE('i');
 2068:     DECLARATION_CARACTERE('j');
 2069:     DECLARATION_CARACTERE('k');
 2070:     DECLARATION_CARACTERE('l');
 2071:     DECLARATION_CARACTERE('m');
 2072:     DECLARATION_CARACTERE('n');
 2073:     DECLARATION_CARACTERE('o');
 2074:     DECLARATION_CARACTERE('p');
 2075:     DECLARATION_CARACTERE('q');
 2076:     DECLARATION_CARACTERE('r');
 2077:     DECLARATION_CARACTERE('s');
 2078:     DECLARATION_CARACTERE('t');
 2079:     DECLARATION_CARACTERE('u');
 2080:     DECLARATION_CARACTERE('v');
 2081:     DECLARATION_CARACTERE('w');
 2082:     DECLARATION_CARACTERE('x');
 2083:     DECLARATION_CARACTERE('y');
 2084:     DECLARATION_CARACTERE('z');
 2085: 
 2086:     DECLARATION_CARACTERE('_');
 2087: 
 2088:     DECLARATION_CARACTERE('1');
 2089:     DECLARATION_CARACTERE('2');
 2090:     DECLARATION_CARACTERE('3');
 2091:     DECLARATION_CARACTERE('4');
 2092:     DECLARATION_CARACTERE('5');
 2093:     DECLARATION_CARACTERE('6');
 2094:     DECLARATION_CARACTERE('7');
 2095:     DECLARATION_CARACTERE('8');
 2096:     DECLARATION_CARACTERE('9');
 2097:     DECLARATION_CARACTERE('0');
 2098: #undef DECLARATION_CARACTERE
 2099: 
 2100:     return;
 2101: }
 2102: 
 2103: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>