Annotation of rpl/src/gestion_variables.c, revision 1.28

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

CVSweb interface <joel.bertrand@systella.fr>