File:  [local] / rpl / src / gestion_variables.c
Revision 1.32: download - view: text, annotated - select for diffs - revision graph
Fri Jun 17 08:47:43 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction des fuites mémoire.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.0.prerelease.0
    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:   Routine de création d'une nouvelle variable
   29:   Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.
   30:   Dans le cas 'V', la variable est volatile.
   31:   Dans le cas 'S', elle est statique.
   32:   Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.
   33:   Dans le cas 'P', la variable est privée.
   34:   Dans le cas 'S', elle est partagée.
   35: --------------------------------------------------------------------------------
   36:   Sortie :
   37: --------------------------------------------------------------------------------
   38:   Effets de bords : néant
   39: ================================================================================
   40: */
   41: 
   42: static logical1
   43: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
   44: {
   45:     int                         i;
   46: 
   47:     struct_liste_variables      *l_nouvelle_variable;
   48:     struct_liste_variables      *l_variable_candidate;
   49:     struct_arbre_variables      *l_variable_courante;
   50:     struct_arbre_variables      *l_variable_precedente;
   51: 
   52:     struct_liste_chainee        *l_nouvel_element;
   53: 
   54:     unsigned char               *ptr;
   55: 
   56:     void                        *pointeur_variable_cree;
   57: 
   58:     if ((*s_etat_processus).s_arbre_variables == NULL)
   59:     {
   60:         if (((*s_etat_processus).s_arbre_variables =
   61:                 malloc(sizeof(struct_arbre_variables))) == NULL)
   62:         {
   63:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   64:             return(d_erreur);
   65:         }
   66: 
   67:         (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
   68:         (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
   69:         (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
   70:         (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
   71: 
   72:         if (((*(*s_etat_processus).s_arbre_variables).noeuds =
   73:                 malloc((*s_etat_processus).nombre_caracteres_variables
   74:                 * sizeof(struct_arbre_variables))) == NULL)
   75:         {
   76:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   77:             return(d_erreur);
   78:         }
   79: 
   80:         for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
   81:         {
   82:             (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
   83:         }
   84:     }
   85: 
   86:     l_variable_precedente = NULL;
   87:     l_variable_courante = (*s_etat_processus).s_arbre_variables;
   88:     ptr = (*s_variable).nom;
   89: 
   90:     while((*ptr) != d_code_fin_chaine)
   91:     {
   92:         BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
   93:                 printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
   94:                 *ptr));
   95: 
   96:         if ((*l_variable_courante).noeuds[(*s_etat_processus)
   97:                 .pointeurs_caracteres_variables[*ptr]] == NULL)
   98:         {
   99:             // Le noeud n'existe pas encore, on le crée et on le marque
  100:             // comme utilisé dans la structure parente.
  101: 
  102:             if (((*l_variable_courante).noeuds[(*s_etat_processus)
  103:                     .pointeurs_caracteres_variables[*ptr]] =
  104:                     malloc(sizeof(struct_arbre_variables))) == NULL)
  105:             {
  106:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  107:                 return(d_erreur);
  108:             }
  109: 
  110:             (*l_variable_courante).noeuds_utilises++;
  111: 
  112:             // La feuille est par défaut vide et aucun élément du tableau noeuds
  113:             // (les branches qui peuvent être issues de ce nouveau noeud)
  114:             // n'est encore utilisée.
  115: 
  116:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  117:                     .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
  118:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  119:                     .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
  120: 
  121:             // Le champ noeud_pere de la structure créée pointe sur
  122:             // la structure parente et l'indice tableau_pere correspond à la
  123:             // position réelle dans le tableau noeuds[] de la structure parente
  124:             // du noeud courant. Cette valeur sera utilisée lors de la
  125:             // destruction du noeud pour annuler le pointeur contenu dans
  126:             // le tableau noeuds[] de la structure parente.
  127: 
  128:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  129:                     .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
  130:                     l_variable_courante;
  131:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  132:                     .pointeurs_caracteres_variables[*ptr]])
  133:                     .indice_tableau_pere = (*s_etat_processus)
  134:                     .pointeurs_caracteres_variables[*ptr];
  135: 
  136:             // Allocation du tableau noeuds[] et initialisation à zéro de
  137:             // tous les pointeurs.
  138: 
  139:             if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
  140:                     .pointeurs_caracteres_variables[*ptr]]).noeuds =
  141:                     malloc((*s_etat_processus).nombre_caracteres_variables
  142:                     * sizeof(struct_arbre_variables))) == NULL)
  143:             {
  144:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  145:                 return(d_erreur);
  146:             }
  147: 
  148:             for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  149:             {
  150:                 (*(*l_variable_courante).noeuds[(*s_etat_processus)
  151:                         .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
  152:                         = NULL;
  153:             }
  154:         }
  155: 
  156:         l_variable_precedente = l_variable_courante;
  157:         l_variable_courante = (*l_variable_courante).noeuds
  158:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
  159:         ptr++;
  160:     }
  161: 
  162:     if ((*l_variable_courante).feuille == NULL)
  163:     {
  164:         // Aucune variable de même nom préexiste. On alloue le premier
  165:         // élément de la liste doublement chaînée contenant toutes les
  166:         // variables de même nom. Cette liste boucle en premier lieu sur
  167:         // elle-même.
  168: 
  169:         if (((*l_variable_courante).feuille = malloc(
  170:                 sizeof(struct_liste_variables))) == NULL)
  171:         {
  172:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  173:             return(d_erreur);
  174:         }
  175: 
  176:         (*(*l_variable_courante).feuille).suivant =
  177:                 (*l_variable_courante).feuille;
  178:         (*(*l_variable_courante).feuille).precedent =
  179:                 (*l_variable_courante).feuille;
  180:         (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
  181:         (*(*l_variable_courante).feuille).noeud = l_variable_courante;
  182: 
  183:         // Allocation de la variable sur l'élément de la liste.
  184: 
  185:         if (((*(*l_variable_courante).feuille).variable =
  186:                 malloc(sizeof(struct_variable))) == NULL)
  187:         { 
  188:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  189:             return(d_erreur);
  190:         }
  191: 
  192:         (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
  193:                 (*s_variable);
  194:         pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
  195:     }
  196:     else
  197:     {
  198:         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
  199:                 == NULL)
  200:         {
  201:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  202:             return(d_erreur);
  203:         }
  204: 
  205:         if ((*s_variable).niveau > 1)
  206:         {
  207:             // Cas d'une variable locale
  208: 
  209:             // Si le niveau de la dernière variable de même nom est
  210:             // supérieur au niveau de la variable locale que l'on veut
  211:             // enregistrer dans la liste, cette liste est incohérente.
  212: 
  213:             BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
  214:                     (*s_variable).niveau,
  215:                     printf("Variable=\"%s\"\n", (*s_variable).nom));
  216: 
  217:             // On ajoute la variable à la liste existante.
  218: 
  219:             (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
  220:             (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
  221:                     .precedent;
  222:             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
  223:             (*(*(*l_variable_courante).feuille).precedent).suivant =
  224:                     l_nouvelle_variable;
  225:             (*(*l_variable_courante).feuille).precedent =
  226:                     l_nouvelle_variable;
  227:             (*l_variable_courante).feuille = l_nouvelle_variable;
  228: 
  229:             if (((*(*l_variable_courante).feuille).variable =
  230:                     malloc(sizeof(struct_variable))) == NULL)
  231:             { 
  232:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  233:                 return(d_erreur);
  234:             }
  235: 
  236:             (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
  237:                     = (*s_variable);
  238:             pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
  239:         }
  240:         else
  241:         {
  242:             // Cas d'une variable globale (niveau 0 [définitions] ou 1
  243:             // [variables globales])
  244: 
  245:             l_variable_candidate = (*l_variable_courante).feuille;
  246: 
  247:             do
  248:             {
  249:                 // S'il y a déjà une variable de même niveau, la pile
  250:                 // est incohérente.
  251: 
  252:                 BUG((*(*l_variable_candidate).variable).niveau ==
  253:                         (*s_variable).niveau,
  254:                         printf("Variable=\"%s\"\n", (*s_variable).nom));
  255: 
  256:                 l_variable_candidate = (*l_variable_candidate).precedent;
  257:             } while((l_variable_candidate != (*l_variable_courante).feuille) &&
  258:                     ((*(*l_variable_candidate).variable).niveau <= 1));
  259: 
  260:             if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
  261:                     .niveau > 1)
  262:             {
  263:                 // Ajout inconditionnel des variables de niveaux 0 et 1
  264:             }
  265:             else
  266:             {
  267:                 l_variable_candidate = (*(*l_variable_courante).feuille)
  268:                         .precedent;
  269:             }
  270: 
  271:             (*l_nouvelle_variable).suivant = l_variable_candidate;
  272:             (*l_nouvelle_variable).precedent = (*l_variable_candidate)
  273:                     .precedent;
  274:             (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
  275:             (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
  276:             (*l_variable_candidate).precedent = l_nouvelle_variable;
  277: 
  278:             if (((*l_nouvelle_variable).variable =
  279:                     malloc(sizeof(struct_variable))) == NULL)
  280:             { 
  281:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  282:                 return(d_erreur);
  283:             }
  284: 
  285:             (*(*l_nouvelle_variable).variable) = (*s_variable);
  286:             pointeur_variable_cree = (*l_nouvelle_variable).variable;
  287:         }
  288:     }
  289: 
  290:     // Ajout de la variable nouvellement créée à la liste par niveaux.
  291:     // Le pointeur contenu dans la structure de description du processus indique
  292:     // toujours le plus haut niveau utilisé.
  293: 
  294:     if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
  295:     {
  296:         // Le niveau courant n'existe pas. Il est créé.
  297: 
  298:         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
  299:                 == NULL)
  300:         {
  301:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  302:             return(d_erreur);
  303:         }
  304: 
  305:         (*l_nouvelle_variable).suivant = l_nouvelle_variable;
  306:         (*l_nouvelle_variable).precedent = l_nouvelle_variable;
  307:         (*l_nouvelle_variable).noeud_pere = NULL;
  308:         (*l_nouvelle_variable).liste = NULL;
  309: 
  310:         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
  311:     }
  312:     else if ((*s_variable).niveau > (*((struct_variable *)
  313:             (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
  314:             .donnee)).niveau)
  315:     {
  316:         // Le niveau courant n'existe pas. Il est créé.
  317: 
  318:         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
  319:                 == NULL)
  320:         {
  321:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  322:             return(d_erreur);
  323:         }
  324: 
  325:         (*l_nouvelle_variable).suivant = (*s_etat_processus)
  326:                 .l_liste_variables_par_niveau;
  327:         (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
  328:                 .l_liste_variables_par_niveau).precedent;
  329:         (*l_nouvelle_variable).noeud_pere = NULL;
  330:         (*l_nouvelle_variable).liste = NULL;
  331:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
  332:                 .suivant = l_nouvelle_variable;
  333:         (*(*s_etat_processus).l_liste_variables_par_niveau).precedent =
  334:                 l_nouvelle_variable;
  335: 
  336:         (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
  337:     }
  338:     else if ((*s_variable).niveau <= 1)
  339:     {
  340:         // Création d'une variable de niveau 0 ou 1
  341: 
  342:         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
  343:                 == NULL)
  344:         {
  345:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  346:             return(d_erreur);
  347:         }
  348: 
  349:         l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
  350: 
  351:         if ((*((struct_variable *) (*(*(*(*s_etat_processus)
  352:                 .l_liste_variables_par_niveau).precedent).liste).donnee))
  353:                 .niveau <= 1)
  354:         {
  355:             l_variable_candidate = (*(*s_etat_processus)
  356:                     .l_liste_variables_par_niveau).precedent;
  357:         }
  358: 
  359:         (*l_nouvelle_variable).suivant = l_variable_candidate;
  360:         (*l_nouvelle_variable).precedent = (*l_variable_candidate)
  361:                 .precedent;
  362:         (*l_nouvelle_variable).noeud_pere = NULL;
  363:         (*l_nouvelle_variable).liste = NULL;
  364:         (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
  365:         (*l_variable_candidate).precedent = l_nouvelle_variable;
  366:     }
  367: 
  368:     // Ajout de la variable en tête de la liste
  369: 
  370:     if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
  371:     {
  372:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  373:         return(d_erreur);
  374:     }
  375: 
  376:     (*l_nouvel_element).suivant = (*(*s_etat_processus)
  377:             .l_liste_variables_par_niveau).liste;
  378:     (*l_nouvel_element).donnee = pointeur_variable_cree;
  379:     (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
  380:             l_nouvel_element;
  381: 
  382:     return(d_absence_erreur);
  383: }
  384: 
  385: 
  386: logical1
  387: creation_variable(struct_processus *s_etat_processus,
  388:         struct_variable *s_variable,
  389:         unsigned char autorisation_creation_variable_statique,
  390:         unsigned char autorisation_creation_variable_partagee)
  391: {
  392:     if ((*s_etat_processus).mode_execution_programme == 'Y')
  393:     {
  394:         (*s_variable).origine = 'P';
  395:     }
  396:     else
  397:     {
  398:         (*s_variable).origine = 'E';
  399:     }
  400: 
  401:     if ((*s_variable).niveau == 0)
  402:     {
  403:         // Un point d'entrée de définition est verrouillé.
  404: 
  405:         if ((*s_variable).origine == 'P')
  406:         {
  407:             (*s_variable).variable_statique.adresse = 0;
  408:             (*s_variable).variable_partagee.adresse = 0;
  409:         }
  410:         else
  411:         {
  412:             (*s_variable).variable_statique.pointeur = NULL;
  413:             (*s_variable).variable_partagee.pointeur = NULL;
  414:         }
  415: 
  416:         (*s_variable).variable_verrouillee = d_vrai;
  417:     }
  418:     else if ((*s_variable).niveau == 1)
  419:     {
  420:         // Une variable globale ne peut être statique.
  421: 
  422:         if ((*s_variable).origine == 'P')
  423:         {
  424:             (*s_variable).variable_statique.adresse = 0;
  425:             (*s_variable).variable_partagee.adresse = 0;
  426:         }
  427:         else
  428:         {
  429:             (*s_variable).variable_statique.pointeur = NULL;
  430:             (*s_variable).variable_partagee.pointeur = NULL;
  431:         }
  432: 
  433:         (*s_variable).variable_verrouillee = d_faux;
  434:     }
  435:     else
  436:     {
  437:         // 0 -> variable volatile
  438:         // adresse de création -> variable statique
  439: 
  440:         if (autorisation_creation_variable_statique == 'V')
  441:         {
  442:             if (autorisation_creation_variable_partagee == 'S')
  443:             {
  444:                 // On force la création d'une variable partagée
  445: 
  446:                 if ((*s_variable).origine == 'P')
  447:                 {
  448:                     (*s_variable).variable_statique.adresse = 0;
  449:                     (*s_variable).variable_partagee.adresse =
  450:                             (*s_etat_processus).position_courante;
  451:                 }
  452:                 else
  453:                 {
  454:                     (*s_variable).variable_statique.pointeur = NULL;
  455:                     (*s_variable).variable_partagee.pointeur =
  456:                             (*s_etat_processus).objet_courant;
  457:                 }
  458:             }
  459:             else
  460:             {
  461:                 // On force la création d'une variable volatile
  462: 
  463:                 if ((*s_variable).origine == 'P')
  464:                 {
  465:                     (*s_variable).variable_statique.adresse = 0;
  466:                     (*s_variable).variable_partagee.adresse = 0;
  467:                 }
  468:                 else
  469:                 {
  470:                     (*s_variable).variable_statique.pointeur = NULL;
  471:                     (*s_variable).variable_partagee.pointeur = NULL;
  472:                 }
  473:             }
  474:         }
  475:         else
  476:         {
  477:             // On force la création d'une variable statique.
  478: 
  479:             if ((*s_variable).origine == 'P')
  480:             {
  481:                 (*s_variable).variable_statique.adresse =
  482:                         (*s_etat_processus).position_courante;
  483:                 (*s_variable).variable_partagee.adresse = 0;
  484:             }
  485:             else
  486:             {
  487:                 (*s_variable).variable_statique.pointeur =
  488:                         (*s_etat_processus).objet_courant;
  489:                 (*s_variable).variable_partagee.pointeur = 0;
  490:             }
  491:         }
  492: 
  493:         (*s_variable).variable_verrouillee = d_faux;
  494:     }
  495: 
  496:     /*
  497:      * Recherche de la feuille correspondante dans l'arbre des variables.
  498:      * Si cette feuille n'existe pas, elle est créée.
  499:      */
  500: 
  501:     if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
  502:     {
  503:         return(d_erreur);
  504:     }
  505: 
  506:     return(d_absence_erreur);
  507: }
  508: 
  509: 
  510: /*
  511: ================================================================================
  512:   Procédure de recherche d'une variable par son nom dans la base
  513: ================================================================================
  514:   Entrée :
  515: --------------------------------------------------------------------------------
  516:   Sortie :
  517: --------------------------------------------------------------------------------
  518:   Effets de bord : néant
  519: ================================================================================
  520: */
  521: 
  522: logical1
  523: recherche_variable(struct_processus *s_etat_processus,
  524:         unsigned char *nom_variable)
  525: {
  526:     int                         pointeur;
  527: 
  528:     struct_arbre_variables      *l_variable_courante;
  529:     struct_liste_pile_systeme   *l_element_courant;
  530: 
  531:     unsigned char               *ptr;
  532: 
  533:     unsigned long               niveau_appel;
  534: 
  535:     if ((*s_etat_processus).s_arbre_variables == NULL)
  536:     {
  537:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  538:         return(d_faux);
  539:     }
  540: 
  541:     l_variable_courante = (*s_etat_processus).s_arbre_variables;
  542:     ptr = nom_variable;
  543: 
  544:     while((*ptr) != d_code_fin_chaine)
  545:     {
  546:         pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
  547: 
  548:         if (pointeur < 0)
  549:         {
  550:             // Caractère hors de l'alphabet des variables
  551: 
  552:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  553:             return(d_faux);
  554:         }
  555: 
  556:         if ((*l_variable_courante).noeuds[pointeur] == NULL)
  557:         {
  558:             // Le chemin de la variable candidate n'existe pas.
  559:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  560:             return(d_faux);
  561:         }
  562: 
  563:         l_variable_courante = (*l_variable_courante).noeuds[pointeur];
  564:         ptr++;
  565:     }
  566: 
  567:     if ((*l_variable_courante).feuille != NULL)
  568:     {
  569:         // Il existe une pile de variables de même nom. Le sommet de la
  570:         // pile est la variable de niveau le plus haut.
  571: 
  572:         l_element_courant = (*s_etat_processus).l_base_pile_systeme;
  573: 
  574:         if (l_element_courant == NULL)
  575:         {
  576:             // Problème : la pile système est vide !
  577:             (*s_etat_processus).erreur_systeme = d_es_pile_vide;
  578:             return(d_faux);
  579:         }
  580: 
  581:         while((*l_element_courant).retour_definition != 'Y')
  582:         {
  583:             l_element_courant = (*l_element_courant).suivant;
  584: 
  585:             if (l_element_courant == NULL)
  586:             {
  587:                 (*s_etat_processus).erreur_systeme = d_es_pile_vide;
  588:                 return(d_faux);
  589:             }
  590:         }
  591: 
  592:         niveau_appel = (*l_element_courant).niveau_courant;
  593: 
  594:         if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
  595:         {
  596:             // Une variable locale est accessible puisque créée dans la
  597:             // fonction courante.
  598: 
  599:             (*s_etat_processus).pointeur_variable_courante =
  600:                     (*(*l_variable_courante).feuille).variable;
  601:             (*s_etat_processus).pointeur_feuille_courante =
  602:                     (*l_variable_courante).feuille;
  603:             return(d_vrai);
  604:         }
  605:         else
  606:         {
  607:             // Aucune variable locale n'est accessible depuis la fonction.
  608:             // Dans ce cas, on prend la variable de niveau le plus bas
  609:             // si ce niveau est inférieur ou égal à 1 (variable globale
  610:             // ou fonction définie par l'utilisateur). Si le niveau de la
  611:             // plus ancienne variable est strictement supérieur à 1, il
  612:             // s'agit d'une variable locale inaccessible.
  613: 
  614:             if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
  615:                     .niveau <= 1)
  616:             {
  617:                 (*s_etat_processus).pointeur_variable_courante =
  618:                         (*(*(*l_variable_courante).feuille).precedent).variable;
  619:                 (*s_etat_processus).pointeur_feuille_courante =
  620:                         (*l_variable_courante).feuille;
  621: 
  622:                 // S'il existe une variable de niveau 0 et une seconde de
  623:                 // niveau 1, la variable de niveau 0 (fonction) est masquée
  624:                 // par celle de niveau 1.
  625: 
  626:                 if (((*(*(*l_variable_courante).feuille).variable).niveau == 0)
  627:                         && ((*(*(*(*l_variable_courante).feuille).precedent)
  628:                         .variable).niveau == 1))
  629:                 {
  630:                     (*s_etat_processus).pointeur_variable_courante =
  631:                             (*(*(*l_variable_courante).feuille).precedent)
  632:                             .variable;
  633:                     (*s_etat_processus).pointeur_feuille_courante =
  634:                             (*l_variable_courante).feuille;
  635:                 }
  636: 
  637:                 return(d_vrai);
  638:             }
  639:         }
  640:     }
  641: 
  642:     (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  643:     return(d_faux);
  644: }
  645: 
  646: 
  647: logical1
  648: recherche_variable_globale(struct_processus *s_etat_processus,
  649:         unsigned char *nom)
  650: {
  651:     logical1            presence_variable;
  652: 
  653:     presence_variable = recherche_variable(s_etat_processus, nom);
  654: 
  655:     if (presence_variable == d_vrai)
  656:     {
  657:         switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
  658:         {
  659:             case 0:
  660:             {
  661:                 // Nous sommes en présence d'une définition et non d'une
  662:                 // variable.
  663: 
  664:                 presence_variable = d_faux;
  665:                 break;
  666:             }
  667: 
  668:             case 1:
  669:             {
  670:                 break;
  671:             }
  672: 
  673:             default:
  674:             {
  675:                 if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
  676:                         .precedent).variable).niveau == 1)
  677:                 {
  678:                     (*s_etat_processus).pointeur_feuille_courante =
  679:                             (*(*s_etat_processus).pointeur_feuille_courante)
  680:                             .precedent;
  681:                     (*s_etat_processus).pointeur_variable_courante =
  682:                             (*(*s_etat_processus).pointeur_feuille_courante)
  683:                             .variable;
  684:                 }
  685:                 else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
  686:                         .precedent).precedent).variable).niveau == 1)
  687:                 {
  688:                     (*s_etat_processus).pointeur_feuille_courante =
  689:                             (*(*(*s_etat_processus).pointeur_feuille_courante)
  690:                             .precedent).precedent;
  691:                     (*s_etat_processus).pointeur_variable_courante =
  692:                             (*(*s_etat_processus).pointeur_feuille_courante)
  693:                             .variable;
  694:                 }
  695:                 else
  696:                 {
  697:                     presence_variable = d_faux;
  698:                 }
  699: 
  700:                 break;
  701:             }
  702:         }
  703:     }
  704: 
  705:     if (presence_variable == d_vrai)
  706:     {
  707:         if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
  708:         {
  709:             // La variable n'est pas globale, elle est partagée.
  710:             presence_variable = d_faux;
  711:             (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
  712:         }
  713:     }
  714: 
  715:     return(presence_variable);
  716: }
  717: 
  718: 
  719: /*
  720: ================================================================================
  721:   Procédure de retrait d'une variable de la base
  722: ================================================================================
  723:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
  724:            les globales) ou strictement globale.
  725: --------------------------------------------------------------------------------
  726:   Sortie :
  727: --------------------------------------------------------------------------------
  728:   Effets de bord : néant
  729: ================================================================================
  730: */
  731: 
  732: logical1
  733: retrait_variable(struct_processus *s_etat_processus,
  734:         unsigned char *nom_variable, unsigned char type)
  735: {
  736:     logical1                    erreur;
  737: 
  738:     struct_arbre_variables      *s_arbre_a_supprimer;
  739:     struct_arbre_variables      *s_arbre_courant;
  740:     struct_arbre_variables      *noeud_courant;
  741: 
  742:     struct_liste_chainee        *l_element_courant;
  743:     struct_liste_chainee        *l_element_precedent;
  744: 
  745:     struct_liste_variables      *variable_a_supprimer;
  746:     struct_liste_variables      *variables_par_niveau;
  747: 
  748:     unsigned long               niveau;
  749: 
  750:     if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
  751:     {
  752:         // Une variable correspondant au nom recherché est accessible.
  753: 
  754:         if (type == 'G')
  755:         {
  756:             if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
  757:             {
  758:                 // La variable obtenue est une variable locale. il faut
  759:                 // s'assurer qu'il existe une variable de niveau 1 de même
  760:                 // nom sur la feuille.
  761: 
  762:                 if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
  763:                         .precedent).variable).niveau <= 1)
  764:                 {
  765:                     (*s_etat_processus).pointeur_feuille_courante =
  766:                             (*(*s_etat_processus).pointeur_feuille_courante)
  767:                             .precedent;
  768:                     (*s_etat_processus).pointeur_variable_courante =
  769:                             (*(*s_etat_processus).pointeur_feuille_courante)
  770:                             .variable;
  771: 
  772:                     // Si la variable retournée est de niveau 0, on regarde
  773:                     // un peu plus loin si une variable de niveau 1 existe.
  774: 
  775:                     if (((*(*(*s_etat_processus).pointeur_feuille_courante)
  776:                             .variable).niveau == 0) &&
  777:                             ((*(*(*(*s_etat_processus)
  778:                             .pointeur_feuille_courante).precedent).variable)
  779:                             .niveau == 1))
  780:                     {
  781:                         (*s_etat_processus).pointeur_feuille_courante =
  782:                                 (*(*s_etat_processus).pointeur_feuille_courante)
  783:                                 .precedent;
  784:                         (*s_etat_processus).pointeur_variable_courante =
  785:                                 (*(*s_etat_processus).pointeur_feuille_courante)
  786:                                 .variable;
  787:                     }
  788:                 }
  789:                 else
  790:                 {
  791:                     // Aucune variable globale (niveau 1) n'existe.
  792: 
  793:                     erreur = d_erreur;
  794:                     (*s_etat_processus).erreur_execution =
  795:                             d_ex_variable_non_definie;
  796:                     return(erreur);
  797:                 }
  798:             }
  799: 
  800:             if ((*(*s_etat_processus).pointeur_variable_courante)
  801:                     .variable_verrouillee == d_vrai)
  802:             {
  803:                 erreur = d_erreur;
  804:                 (*s_etat_processus).erreur_execution =
  805:                         d_ex_variable_verrouillee;
  806:                 return(erreur);
  807:             }
  808:         }
  809: 
  810:         // Suppression de la variable de la liste.
  811:         // Deux cas peuvent survenir :
  812:         // 1/ les pointeurs sur la variable et la variable suivante
  813:         // sont identiques et on supprime la variable ainsi que la feuille
  814:         // associée ;
  815:         // 2/ ces deux pointeurs sont différents et se contente de retirer
  816:         // la structure décrivant la variable.
  817: 
  818:         if ((*s_etat_processus).pointeur_feuille_courante ==
  819:                 (*(*s_etat_processus).pointeur_feuille_courante).suivant)
  820:         {
  821:             // Cas 1 :
  822:             // On retire la variable du noeud en décrémentant le nombre
  823:             // de feuilles de ce noeud. Si le nombre de feuilles du noeud
  824:             // est nul, on retire les noeuds récursivement jusqu'à obtenir
  825:             // un nombre non nul de feuilles utilisées (ou la racine des
  826:             // variables).
  827: 
  828:             variable_a_supprimer = (*s_etat_processus)
  829:                     .pointeur_feuille_courante;
  830:             s_arbre_courant = (*variable_a_supprimer).noeud_pere;
  831:             noeud_courant = (*variable_a_supprimer).noeud;
  832: 
  833:             BUG((*s_arbre_courant).noeuds_utilises == 0,
  834:                     uprintf("Freed node !\n"));
  835:             (*s_arbre_courant).noeuds_utilises--;
  836: 
  837:             while((*s_arbre_courant).noeuds_utilises == 0)
  838:             {
  839:                 s_arbre_a_supprimer = s_arbre_courant;
  840:                 s_arbre_courant = (*s_arbre_courant).noeud_pere;
  841: 
  842:                 if (s_arbre_courant == NULL)
  843:                 {
  844:                     free((*s_arbre_a_supprimer).noeuds);
  845:                     free(s_arbre_a_supprimer);
  846:                     break;
  847:                 }
  848: 
  849:                 // s_arbre_a_supprimer contient la structure de feuille qui
  850:                 // vient d'être libérée. Il s'agit maintenant
  851:                 // d'annuler le pointeur dans le tableau noeuds de la structure
  852:                 // pointée par noeud_pere, soit s_arbre_courant.
  853: 
  854:                 BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
  855:                         uprintf("Invalid pointer !\n"));
  856:                 (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
  857:                         .indice_tableau_pere] = NULL;
  858: 
  859:                 free((*s_arbre_a_supprimer).noeuds);
  860:                 free(s_arbre_a_supprimer);
  861: 
  862:                 BUG((*s_arbre_courant).noeuds_utilises == 0,
  863:                         uprintf("Freed node !\n"));
  864:                 (*s_arbre_courant).noeuds_utilises--;
  865:             }
  866:         }
  867:         else
  868:         {
  869:             // Cas 2 :
  870:             // On retire la variable de la liste.
  871: 
  872:             variable_a_supprimer = (*s_etat_processus)
  873:                     .pointeur_feuille_courante;
  874: 
  875:             (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
  876:                     .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
  877:                     .suivant;
  878:             (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
  879:                     .precedent = (*(*s_etat_processus)
  880:                     .pointeur_feuille_courante).precedent;
  881: 
  882:             noeud_courant = NULL;
  883:         }
  884: 
  885:         // Dans tous les cas, on retire la variable de la liste des variables
  886:         // par niveau.
  887: 
  888:         niveau = (*(*variable_a_supprimer).variable).niveau;
  889:         variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
  890: 
  891:         if (variables_par_niveau != NULL)
  892:         {
  893:             do
  894:             {
  895:                 l_element_courant = (*variables_par_niveau).liste;
  896: 
  897:                 if (l_element_courant != NULL)
  898:                 {
  899:                     if ((*((struct_variable *) (*l_element_courant).donnee))
  900:                             .niveau == niveau)
  901:                     {
  902:                         // On parcourt le bon niveau.
  903: 
  904:                         l_element_precedent = NULL;
  905: 
  906:                         while(l_element_courant != NULL)
  907:                         {
  908:                             // Tant que l_element_courant est non nul, il reste
  909:                             // des variables à explorer dans le niveau courant.
  910: 
  911:                             if ((*l_element_courant).donnee ==
  912:                                     (void *) (*variable_a_supprimer).variable)
  913:                             {
  914:                                 // On a trouvé la variable à supprimer.
  915: 
  916:                                 if (l_element_precedent == NULL)
  917:                                 {
  918:                                     (*variables_par_niveau).liste =
  919:                                             (*l_element_courant).suivant;
  920:                                 }
  921:                                 else
  922:                                 {
  923:                                     (*l_element_precedent).suivant =
  924:                                             (*l_element_courant).suivant;
  925:                                 }
  926: 
  927:                                 free(l_element_courant);
  928:                                 break;
  929:                             }
  930: 
  931:                             l_element_precedent = l_element_courant;
  932:                             l_element_courant = (*l_element_courant).suivant;
  933:                         }
  934:                     }
  935:                 }
  936: 
  937:                 variables_par_niveau = (*variables_par_niveau).suivant;
  938: 
  939:             } while(variables_par_niveau != (*s_etat_processus)
  940:                     .l_liste_variables_par_niveau);
  941:         }
  942: 
  943:         // Puis on libère le contenu de la variable.
  944: 
  945:         free((*(*variable_a_supprimer).variable).nom);
  946:         liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
  947:         free((*variable_a_supprimer).variable);
  948: 
  949:         erreur = d_absence_erreur;
  950: 
  951:         if (noeud_courant != NULL)
  952:         {
  953:             free((*noeud_courant).feuille);
  954:             free((*noeud_courant).noeuds);
  955:             free(noeud_courant);
  956:         }
  957:     }
  958:     else
  959:     {
  960:         // Aucune variable n'est accessible depuis le point courant du
  961:         // programme.
  962: 
  963:         erreur = d_erreur;
  964:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  965:     }
  966: 
  967:     return(erreur);
  968: }
  969: 
  970: 
  971: /*
  972: ================================================================================
  973:   Procédure de retrait des variables de niveau strictement supérieur au
  974:   niveau courant
  975: ================================================================================
  976:   Entrée :
  977: --------------------------------------------------------------------------------
  978:   Sortie :
  979: --------------------------------------------------------------------------------
  980:   Effets de bord : néant
  981: ================================================================================
  982: */
  983: 
  984: logical1
  985: retrait_variable_par_niveau(struct_processus *s_etat_processus)
  986: {
  987:     struct_liste_variables          *l_element_a_supprimer;
  988: 
  989:     // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
  990:     // La tête de la pile contient toujours les variables de plus haut niveau
  991:     // créées.
  992: 
  993:     while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
  994:     {
  995:         if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
  996:         {
  997:             // Si le niveau ne contient aucune variable, on le détruit.
  998:             // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
  999:             // faire.
 1000:         }
 1001:         else
 1002:         {
 1003:             // Le niveau contient des variables.
 1004: 
 1005:             if ((*((struct_variable *) (*(*(*s_etat_processus)
 1006:                     .l_liste_variables_par_niveau).liste).donnee)).niveau
 1007:                     <= (*s_etat_processus).niveau_courant)
 1008:             {
 1009:                 // On a retiré de l'arbre des variables toutes les
 1010:                 // variables de niveau strictement supérieur au niveau
 1011:                 // courant.
 1012: 
 1013:                 break;
 1014:             }
 1015: 
 1016:             while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
 1017:                     != NULL)
 1018:             {
 1019:                 // Sauvegarde des variables statiques.
 1020: 
 1021:                 if ((*((struct_variable *) (*(*(*s_etat_processus)
 1022:                         .l_liste_variables_par_niveau).liste).donnee)).origine
 1023:                         == 'P')
 1024:                 {
 1025:                     if ((*((struct_variable *) (*(*(*s_etat_processus)
 1026:                             .l_liste_variables_par_niveau).liste).donnee))
 1027:                             .variable_statique.adresse != 0)
 1028:                     {
 1029:                         if (recherche_variable_statique(s_etat_processus,
 1030:                                 (*((struct_variable *) (*(*(*s_etat_processus)
 1031:                                 .l_liste_variables_par_niveau).liste).donnee))
 1032:                                 .nom, (*((struct_variable *)
 1033:                                 (*(*(*s_etat_processus)
 1034:                                 .l_liste_variables_par_niveau).liste).donnee))
 1035:                                 .variable_statique, ((*s_etat_processus)
 1036:                                 .mode_execution_programme
 1037:                                  == 'Y') ? 'P' : 'E') == d_vrai)
 1038:                         {
 1039:                             (*s_etat_processus).s_liste_variables_statiques
 1040:                                     [(*s_etat_processus)
 1041:                                     .position_variable_statique_courante]
 1042:                                     .objet = (*((struct_variable *)
 1043:                                     (*(*(*s_etat_processus)
 1044:                                     .l_liste_variables_par_niveau).liste)
 1045:                                     .donnee)).objet;
 1046:                         }
 1047:                         else
 1048:                         {
 1049:                             (*s_etat_processus).erreur_systeme =
 1050:                                     d_es_variable_introuvable;
 1051:                         }
 1052: 
 1053:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1054:                                 .l_liste_variables_par_niveau).liste).donnee))
 1055:                                 .objet = NULL;
 1056:                     }
 1057:                 }
 1058:                 else
 1059:                 {
 1060:                     if ((*((struct_variable *) (*(*(*s_etat_processus)
 1061:                             .l_liste_variables_par_niveau).liste).donnee))
 1062:                             .variable_statique.pointeur != NULL)
 1063:                     {
 1064:                         /*
 1065:                          * Gestion des variables statiques
 1066:                          */
 1067: 
 1068:                         if (recherche_variable_statique(s_etat_processus,
 1069:                                 (*((struct_variable *) (*(*(*s_etat_processus)
 1070:                                 .l_liste_variables_par_niveau).liste).donnee))
 1071:                                 .nom, (*((struct_variable *)
 1072:                                 (*(*(*s_etat_processus)
 1073:                                 .l_liste_variables_par_niveau).liste).donnee))
 1074:                                 .variable_statique, ((*s_etat_processus)
 1075:                                 .mode_execution_programme
 1076:                                  == 'Y') ? 'P' : 'E') == d_vrai)
 1077:                         {
 1078:                             (*s_etat_processus).s_liste_variables_statiques
 1079:                                     [(*s_etat_processus)
 1080:                                     .position_variable_statique_courante]
 1081:                                     .objet = (*((struct_variable *)
 1082:                                     (*(*(*s_etat_processus)
 1083:                                     .l_liste_variables_par_niveau).liste)
 1084:                                     .donnee)).objet;
 1085:                         }
 1086:                         else
 1087:                         {
 1088:                             (*s_etat_processus).erreur_systeme =
 1089:                                     d_es_variable_introuvable;
 1090:                             return(d_erreur);
 1091:                         }
 1092: 
 1093:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1094:                                 .l_liste_variables_par_niveau).liste).donnee))
 1095:                                 .objet = NULL;
 1096:                     }
 1097:                 }
 1098: 
 1099:                 if (retrait_variable(s_etat_processus,
 1100:                         (*((struct_variable *) (*(*(*s_etat_processus)
 1101:                         .l_liste_variables_par_niveau).liste).donnee)).nom,
 1102:                         'L') == d_erreur)
 1103:                 {
 1104:                     return(d_erreur);
 1105:                 }
 1106:             }
 1107:         }
 1108: 
 1109:         // On retire l'élément de la liste doublement chaînée et circulaire.
 1110: 
 1111:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
 1112:                 = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
 1113:         (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
 1114:                 = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
 1115: 
 1116:         l_element_a_supprimer = (*s_etat_processus)
 1117:                 .l_liste_variables_par_niveau;
 1118:         (*s_etat_processus).l_liste_variables_par_niveau =
 1119:                 (*l_element_a_supprimer).suivant;
 1120:         free(l_element_a_supprimer);
 1121:     }
 1122: 
 1123:     return(d_absence_erreur);
 1124: }
 1125: 
 1126: 
 1127: /*
 1128: ================================================================================
 1129:   Procédure de retrait des toutes les variables locales et globales
 1130: ================================================================================
 1131:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
 1132:            de niveau 0)
 1133: --------------------------------------------------------------------------------
 1134:   Sortie :
 1135: --------------------------------------------------------------------------------
 1136:   Effets de bord : néant
 1137: ================================================================================
 1138: */
 1139: 
 1140: void
 1141: liberation_arbre_variables(struct_processus *s_etat_processus,
 1142:         struct_arbre_variables *arbre, logical1 retrait_definitions)
 1143: {
 1144:     int                     i;
 1145: 
 1146:     struct_liste_chainee    *l_element_courant_liste;
 1147:     struct_liste_chainee    *l_element_suivant_liste;
 1148: 
 1149:     struct_liste_variables  *l_element_courant;
 1150:     struct_liste_variables  *l_element_suivant;
 1151: 
 1152:     // Libération de l'arbre des variables. Le contenu des variables n'est
 1153:     // pas détruit par cette opération, il sera détruit lors de la libération
 1154:     // de la liste des variables par niveau.
 1155: 
 1156:     l_element_courant = (*arbre).feuille;
 1157: 
 1158:     if (l_element_courant != NULL)
 1159:     {
 1160:         do
 1161:         {
 1162:             l_element_suivant = (*l_element_courant).suivant;
 1163:             free(l_element_courant);
 1164:             l_element_courant = l_element_suivant;
 1165:         } while(l_element_courant != (*arbre).feuille);
 1166:     }
 1167: 
 1168:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
 1169:     {
 1170:         if ((*arbre).noeuds[i] != NULL)
 1171:         {
 1172:             liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
 1173:                     retrait_definitions);
 1174:         }
 1175:     }
 1176: 
 1177:     // Suppression de la liste des variables par niveau.
 1178: 
 1179:     if (arbre == (*s_etat_processus).s_arbre_variables)
 1180:     {
 1181:         l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
 1182: 
 1183:         if (l_element_courant != NULL)
 1184:         {
 1185:             do
 1186:             {
 1187:                 l_element_courant_liste = (*l_element_courant).liste;
 1188: 
 1189:                 while(l_element_courant_liste != NULL)
 1190:                 {
 1191:                     if ((retrait_definitions == d_vrai) ||
 1192:                             ((*((struct_variable *) (*l_element_courant_liste)
 1193:                             .donnee)).niveau >= 1))
 1194:                     {
 1195:                         liberation(s_etat_processus, (*((struct_variable *)
 1196:                                 (*l_element_courant_liste).donnee)).objet);
 1197:                         free((*((struct_variable *) (*l_element_courant_liste)
 1198:                                 .donnee)).nom);
 1199:                         free((*l_element_courant_liste).donnee);
 1200:                     }
 1201: 
 1202:                     l_element_suivant_liste =
 1203:                             (*l_element_courant_liste).suivant;
 1204:                     free(l_element_courant_liste);
 1205:                     l_element_courant_liste = l_element_suivant_liste;
 1206:                 }
 1207: 
 1208:                 l_element_suivant = (*l_element_courant).suivant;
 1209:                 free(l_element_courant);
 1210:                 l_element_courant = l_element_suivant;
 1211:             } while(l_element_courant != (*s_etat_processus)
 1212:                     .l_liste_variables_par_niveau);
 1213:         }
 1214:     }
 1215: 
 1216:     free((*arbre).noeuds);
 1217:     free(arbre);
 1218: 
 1219:     return;
 1220: }
 1221: 
 1222: 
 1223: /*
 1224: ================================================================================
 1225:   Procédure de copie de l'arbre des variables
 1226: ================================================================================
 1227:   Entrée :
 1228: --------------------------------------------------------------------------------
 1229:   Sortie :
 1230: --------------------------------------------------------------------------------
 1231:   Effets de bord : néant
 1232: ================================================================================
 1233: */
 1234: 
 1235: struct_arbre_variables *
 1236: copie_arbre_variables(struct_processus *s_etat_processus)
 1237: {
 1238:     // Les définitions sont partagées entre tous les threads et ne sont pas
 1239:     // copiées.
 1240:     //
 1241:     // NB : on ne copie que les variables de niveaux 0 et 1, les autres
 1242:     // variables locales étant masquées par le processus de création de thread
 1243:     // ou de processus, elles sont inaccessibles.
 1244: 
 1245:     BUG(1, uprintf("Oops !\n"));
 1246: 
 1247:     return(d_absence_erreur);
 1248: }
 1249: 
 1250: 
 1251: /*
 1252: ================================================================================
 1253:   Procédure d'initialisation de la table de correspondance des variables
 1254: ================================================================================
 1255:   Entrée :
 1256: --------------------------------------------------------------------------------
 1257:   Sortie :
 1258: --------------------------------------------------------------------------------
 1259:   Effets de bord : néant
 1260: ================================================================================
 1261: */
 1262: 
 1263: /*
 1264:  * Caractères autorisés dans les instructions
 1265:  *
 1266:  * 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
 1267:  * 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
 1268:  * _
 1269:  * 1 2 3 4 5 6 7 8 9 0
 1270:  */
 1271: 
 1272: void
 1273: initialisation_variables(struct_processus *s_etat_processus)
 1274: {
 1275:     int             decalage;
 1276:     int             i;
 1277:     int             longueur_tableau;
 1278: 
 1279:     unsigned char   caractere;
 1280: 
 1281:     // Récupération de la longueur d'un unsigned char
 1282: 
 1283:     longueur_tableau = 1;
 1284:     decalage = 0;
 1285:     caractere = 1;
 1286: 
 1287:     while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
 1288:     {
 1289:         decalage++;
 1290:         longueur_tableau *= 2;
 1291:     }
 1292: 
 1293:     if (((*s_etat_processus).pointeurs_caracteres_variables =
 1294:             malloc(longueur_tableau * sizeof(int))) == NULL)
 1295:     {
 1296:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1297:         return;
 1298:     }
 1299: 
 1300:     for(i = 0; i < longueur_tableau; i++)
 1301:     {
 1302:         (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
 1303:     }
 1304: 
 1305:     (*s_etat_processus).nombre_caracteres_variables = 0;
 1306: 
 1307: #define DECLARATION_CARACTERE(c) \
 1308:         do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
 1309:         (*s_etat_processus).nombre_caracteres_variables++; } while(0)
 1310: 
 1311:     DECLARATION_CARACTERE('A');
 1312:     DECLARATION_CARACTERE('B');
 1313:     DECLARATION_CARACTERE('C');
 1314:     DECLARATION_CARACTERE('D');
 1315:     DECLARATION_CARACTERE('E');
 1316:     DECLARATION_CARACTERE('F');
 1317:     DECLARATION_CARACTERE('G');
 1318:     DECLARATION_CARACTERE('H');
 1319:     DECLARATION_CARACTERE('I');
 1320:     DECLARATION_CARACTERE('J');
 1321:     DECLARATION_CARACTERE('K');
 1322:     DECLARATION_CARACTERE('L');
 1323:     DECLARATION_CARACTERE('M');
 1324:     DECLARATION_CARACTERE('N');
 1325:     DECLARATION_CARACTERE('O');
 1326:     DECLARATION_CARACTERE('P');
 1327:     DECLARATION_CARACTERE('Q');
 1328:     DECLARATION_CARACTERE('R');
 1329:     DECLARATION_CARACTERE('S');
 1330:     DECLARATION_CARACTERE('T');
 1331:     DECLARATION_CARACTERE('U');
 1332:     DECLARATION_CARACTERE('V');
 1333:     DECLARATION_CARACTERE('W');
 1334:     DECLARATION_CARACTERE('X');
 1335:     DECLARATION_CARACTERE('Y');
 1336:     DECLARATION_CARACTERE('Z');
 1337: 
 1338:     DECLARATION_CARACTERE('a');
 1339:     DECLARATION_CARACTERE('b');
 1340:     DECLARATION_CARACTERE('c');
 1341:     DECLARATION_CARACTERE('d');
 1342:     DECLARATION_CARACTERE('e');
 1343:     DECLARATION_CARACTERE('f');
 1344:     DECLARATION_CARACTERE('g');
 1345:     DECLARATION_CARACTERE('h');
 1346:     DECLARATION_CARACTERE('i');
 1347:     DECLARATION_CARACTERE('j');
 1348:     DECLARATION_CARACTERE('k');
 1349:     DECLARATION_CARACTERE('l');
 1350:     DECLARATION_CARACTERE('m');
 1351:     DECLARATION_CARACTERE('n');
 1352:     DECLARATION_CARACTERE('o');
 1353:     DECLARATION_CARACTERE('p');
 1354:     DECLARATION_CARACTERE('q');
 1355:     DECLARATION_CARACTERE('r');
 1356:     DECLARATION_CARACTERE('s');
 1357:     DECLARATION_CARACTERE('t');
 1358:     DECLARATION_CARACTERE('u');
 1359:     DECLARATION_CARACTERE('v');
 1360:     DECLARATION_CARACTERE('w');
 1361:     DECLARATION_CARACTERE('x');
 1362:     DECLARATION_CARACTERE('y');
 1363:     DECLARATION_CARACTERE('z');
 1364: 
 1365:     DECLARATION_CARACTERE('_');
 1366: 
 1367:     DECLARATION_CARACTERE('1');
 1368:     DECLARATION_CARACTERE('2');
 1369:     DECLARATION_CARACTERE('3');
 1370:     DECLARATION_CARACTERE('4');
 1371:     DECLARATION_CARACTERE('5');
 1372:     DECLARATION_CARACTERE('6');
 1373:     DECLARATION_CARACTERE('7');
 1374:     DECLARATION_CARACTERE('8');
 1375:     DECLARATION_CARACTERE('9');
 1376:     DECLARATION_CARACTERE('0');
 1377: #undef DECLARATION_CARACTERE
 1378: 
 1379:     return;
 1380: }
 1381: 
 1382: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>