File:  [local] / rpl / src / gestion_variables.c
Revision 1.38: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 15:03:58 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Les fonctions de copie de l'arbre des variables fonctionnement et SPAWN
est utilisable.

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

CVSweb interface <joel.bertrand@systella.fr>