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

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

CVSweb interface <joel.bertrand@systella.fr>