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

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

CVSweb interface <joel.bertrand@systella.fr>