File:  [local] / rpl / src / gestion_variables.c
Revision 1.39: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 15:26:29 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.0.prerelease.2
    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>