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

1.1       bertrand    1: /*
                      2: ================================================================================
1.35      bertrand    3:   RPL/2 (R) version 4.1.0.prerelease.1
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: ================================================================================
1.33      bertrand   28:   Fonction de debug
                     29: ================================================================================
                     30:   Entrée :
                     31: --------------------------------------------------------------------------------
                     32:   Sortie :
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bords : néant
                     35: ================================================================================
                     36: */
                     37: 
                     38: static void
                     39: liste_variables_par_niveaux(struct_processus *s_etat_processus)
                     40: {
                     41:    int                     c;
                     42: 
                     43:    logical1                fin;
                     44: 
                     45:    struct_liste_variables  *l;
                     46: 
                     47:    struct_liste_chainee    *e;
                     48: 
                     49:    printf("===========================================================\n");
                     50:    printf("  Liste des variables par niveaux\n");
                     51:    printf("===========================================================\n");
                     52: 
1.34      bertrand   53:    if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
                     54:    {
                     55:        printf("===========================================================\n");
                     56:        return;
                     57:    }
                     58: 
1.33      bertrand   59:    printf("Backward\n");
                     60:    l = (*s_etat_processus).l_liste_variables_par_niveau;
                     61:    c = 0;
                     62:    fin = d_faux;
                     63: 
                     64:    do
                     65:    {
                     66:        l = l->precedent;
                     67:        e = l->liste;
                     68: 
                     69:        while(e != NULL)
                     70:        {
                     71:            printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
                     72:                    e->donnee, ((struct_variable *) e->donnee)->niveau);
                     73:            e = e->suivant;
                     74:            c++;
                     75:            if (c > 100)
                     76:            {
                     77:                fin = d_vrai;
                     78:                break;
                     79:            }
                     80:        }
                     81: 
                     82:        printf("\n");
                     83: 
                     84:    } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
                     85: 
                     86:    printf("Forward\n");
                     87:    l = (*s_etat_processus).l_liste_variables_par_niveau;
                     88:    c = 0;
                     89: 
                     90:    do
                     91:    {
                     92:        e = l->liste;
                     93: 
                     94:        while(e != NULL)
                     95:        {
                     96:            printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
                     97:                    e->donnee, ((struct_variable *) e->donnee)->niveau);
                     98:            e = e->suivant;
                     99:            c++;
                    100:            if (c > 100) exit(0);
                    101:        }
                    102: 
                    103:        printf("\n");
                    104: 
                    105:        l = l->suivant;
                    106:    } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
                    107: 
                    108:    printf("===========================================================\n");
                    109: 
                    110:    if (fin == d_vrai) exit(0);
                    111: 
                    112:    return;
                    113: }
                    114: 
                    115: static void
                    116: liste_variables_tas(struct_processus *s_etat_processus,
                    117:        struct_arbre_variables *arbre)
                    118: {
                    119:    int                     c;
                    120:    int                     i;
                    121: 
                    122:    logical1                fin;
                    123: 
                    124:    struct_liste_variables  *l;
                    125: 
                    126:    fin = d_faux;
                    127: 
1.34      bertrand  128:    if (arbre == NULL)
                    129:    {
                    130:        return;
                    131:    }
                    132: 
                    133:    printf(">>> Position :                  %d\n",
                    134:            (*arbre).indice_tableau_pere);
                    135:    printf(">>> Nombre de noeuds utilisés : %u\n",
                    136:            (*arbre).noeuds_utilises);
                    137:    printf(">>> Noeuds fils : ");
                    138: 
                    139:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    140:    {
                    141:        if ((*arbre).noeuds[i] != NULL)
                    142:        {
                    143:            printf("%d ", i);
                    144:        }
                    145:    }
                    146: 
                    147:    printf("\b\n");
                    148: 
1.33      bertrand  149:    if ((*arbre).feuille != NULL)
                    150:    {
1.34      bertrand  151:        printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
1.33      bertrand  152: 
                    153:        printf("  Backward\n");
                    154: 
                    155:        l = (*arbre).feuille;
                    156:        c = 0;
                    157:        fin = d_faux;
                    158: 
                    159:        do
                    160:        {
                    161:            l = l->precedent;
                    162:            c++;
                    163:            if (c > 100)
                    164:            {
                    165:                fin = d_vrai;
                    166:                break;
                    167:            }
                    168:            printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
                    169:                    l->variable->niveau);
                    170:        } while((*arbre).feuille != l);
                    171: 
                    172:        printf("  Forward\n");
                    173: 
                    174:        l = (*arbre).feuille;
                    175:        c = 0;
                    176: 
                    177:        do
                    178:        {
                    179:            c++;
                    180:            if (c > 100) exit(0);
                    181:            printf("    %s (%p, %d)\n", l->variable->nom, l->variable,
                    182:                    l->variable->niveau);
                    183:            l = l->suivant;
                    184:        } while((*arbre).feuille != l);
                    185:    }
                    186: 
1.34      bertrand  187:    printf("-----------------------------------------------------------\n");
                    188: 
1.33      bertrand  189:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    190:    {
                    191:        if ((*arbre).noeuds[i] != NULL)
                    192:        {
1.34      bertrand  193: 
1.33      bertrand  194:            liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
                    195:        }
                    196:    }
                    197: 
                    198:    if (fin == d_vrai) exit(0);
                    199: 
                    200:    return;
                    201: }
                    202: 
                    203: 
                    204: static void
                    205: liste_variables_par_feuilles(struct_processus *s_etat_processus)
                    206: {
                    207:    printf("===========================================================\n");
                    208:    printf("  Liste des variables sur le tas\n");
                    209:    printf("===========================================================\n");
                    210: 
                    211:    liste_variables_tas(s_etat_processus,
                    212:            (*s_etat_processus).s_arbre_variables);
                    213: 
                    214:    printf("===========================================================\n");
                    215: 
                    216:    return;
                    217: }
                    218: 
                    219: 
                    220: /*
                    221: ================================================================================
1.1       bertrand  222:   Routine de création d'une nouvelle variable
1.33      bertrand  223: ================================================================================
                    224:   Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
                    225:   dans le cas 'v', la variable est volatile.
                    226:   dans le cas 's', elle est statique.
                    227:   Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
                    228:   dans le cas 'p', la variable est privée.
                    229:   dans le cas 's', elle est partagée.
1.1       bertrand  230: --------------------------------------------------------------------------------
                    231:   Sortie :
                    232: --------------------------------------------------------------------------------
                    233:   Effets de bords : néant
                    234: ================================================================================
                    235: */
                    236: 
1.25      bertrand  237: static logical1
                    238: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1       bertrand  239: {
1.25      bertrand  240:    int                         i;
                    241: 
1.33      bertrand  242:    logical1                    niveau_acceptable;
                    243: 
1.25      bertrand  244:    struct_liste_variables      *l_nouvelle_variable;
                    245:    struct_liste_variables      *l_variable_candidate;
1.33      bertrand  246: 
1.28      bertrand  247:    struct_arbre_variables      *l_variable_courante;
                    248:    struct_arbre_variables      *l_variable_precedente;
1.1       bertrand  249: 
1.25      bertrand  250:    struct_liste_chainee        *l_nouvel_element;
1.1       bertrand  251: 
1.25      bertrand  252:    unsigned char               *ptr;
1.1       bertrand  253: 
1.31      bertrand  254:    void                        *pointeur_variable_cree;
                    255: 
1.25      bertrand  256:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand  257:    {
1.25      bertrand  258:        if (((*s_etat_processus).s_arbre_variables =
                    259:                malloc(sizeof(struct_arbre_variables))) == NULL)
                    260:        {
                    261:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    262:            return(d_erreur);
                    263:        }
                    264: 
                    265:        (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
                    266:        (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31      bertrand  267:        (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28      bertrand  268:        (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1       bertrand  269: 
1.30      bertrand  270:        if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.25      bertrand  271:                malloc((*s_etat_processus).nombre_caracteres_variables
                    272:                * sizeof(struct_arbre_variables))) == NULL)
1.1       bertrand  273:        {
1.25      bertrand  274:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    275:            return(d_erreur);
                    276:        }
                    277: 
                    278:        for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    279:        {
1.28      bertrand  280:            (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25      bertrand  281:        }
                    282:    }
                    283: 
1.28      bertrand  284:    l_variable_precedente = NULL;
1.25      bertrand  285:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
                    286:    ptr = (*s_variable).nom;
                    287: 
                    288:    while((*ptr) != d_code_fin_chaine)
                    289:    {
                    290:        BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
                    291:                printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
                    292:                *ptr));
                    293: 
1.28      bertrand  294:        if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  295:                .pointeurs_caracteres_variables[*ptr]] == NULL)
                    296:        {
1.31      bertrand  297:            // Le noeud n'existe pas encore, on le crée et on le marque
                    298:            // comme utilisé dans la structure parente.
1.25      bertrand  299: 
1.28      bertrand  300:            if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  301:                    .pointeurs_caracteres_variables[*ptr]] =
                    302:                    malloc(sizeof(struct_arbre_variables))) == NULL)
                    303:            {
                    304:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    305:                return(d_erreur);
                    306:            }
                    307: 
1.28      bertrand  308:            (*l_variable_courante).noeuds_utilises++;
1.31      bertrand  309: 
                    310:            // La feuille est par défaut vide et aucun élément du tableau noeuds
                    311:            // (les branches qui peuvent être issues de ce nouveau noeud)
                    312:            // n'est encore utilisée.
                    313: 
1.28      bertrand  314:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  315:                    .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28      bertrand  316:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  317:                    .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31      bertrand  318: 
                    319:            // Le champ noeud_pere de la structure créée pointe sur
                    320:            // la structure parente et l'indice tableau_pere correspond à la
                    321:            // position réelle dans le tableau noeuds[] de la structure parente
                    322:            // du noeud courant. Cette valeur sera utilisée lors de la
                    323:            // destruction du noeud pour annuler le pointeur contenu dans
                    324:            // le tableau noeuds[] de la structure parente.
                    325: 
1.28      bertrand  326:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    327:                    .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31      bertrand  328:                    l_variable_courante;
                    329:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    330:                    .pointeurs_caracteres_variables[*ptr]])
                    331:                    .indice_tableau_pere = (*s_etat_processus)
                    332:                    .pointeurs_caracteres_variables[*ptr];
                    333: 
                    334:            // Allocation du tableau noeuds[] et initialisation à zéro de
                    335:            // tous les pointeurs.
1.25      bertrand  336: 
1.28      bertrand  337:            if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
                    338:                    .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.25      bertrand  339:                    malloc((*s_etat_processus).nombre_caracteres_variables
                    340:                    * sizeof(struct_arbre_variables))) == NULL)
                    341:            {
                    342:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    343:                return(d_erreur);
                    344:            }
                    345: 
                    346:            for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    347:            {
1.28      bertrand  348:                (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    349:                        .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                    350:                        = NULL;
1.25      bertrand  351:            }
                    352:        }
                    353: 
1.28      bertrand  354:        l_variable_precedente = l_variable_courante;
                    355:        l_variable_courante = (*l_variable_courante).noeuds
1.25      bertrand  356:                [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
                    357:        ptr++;
                    358:    }
                    359: 
                    360:    if ((*l_variable_courante).feuille == NULL)
                    361:    {
                    362:        // Aucune variable de même nom préexiste. On alloue le premier
                    363:        // élément de la liste doublement chaînée contenant toutes les
                    364:        // variables de même nom. Cette liste boucle en premier lieu sur
                    365:        // elle-même.
                    366: 
                    367:        if (((*l_variable_courante).feuille = malloc(
                    368:                sizeof(struct_liste_variables))) == NULL)
                    369:        {
                    370:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    371:            return(d_erreur);
                    372:        }
                    373: 
1.34      bertrand  374:        (*l_variable_courante).noeuds_utilises++;
                    375: 
1.25      bertrand  376:        (*(*l_variable_courante).feuille).suivant =
                    377:                (*l_variable_courante).feuille;
                    378:        (*(*l_variable_courante).feuille).precedent =
                    379:                (*l_variable_courante).feuille;
1.28      bertrand  380:        (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32      bertrand  381:        (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25      bertrand  382: 
                    383:        // Allocation de la variable sur l'élément de la liste.
                    384: 
                    385:        if (((*(*l_variable_courante).feuille).variable =
                    386:                malloc(sizeof(struct_variable))) == NULL)
                    387:        { 
                    388:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    389:            return(d_erreur);
                    390:        }
                    391: 
                    392:        (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
                    393:                (*s_variable);
1.31      bertrand  394:        pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25      bertrand  395:    }
                    396:    else
                    397:    {
1.28      bertrand  398:        if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
                    399:                == NULL)
                    400:        {
                    401:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    402:            return(d_erreur);
                    403:        }
                    404: 
1.25      bertrand  405:        if ((*s_variable).niveau > 1)
                    406:        {
                    407:            // Cas d'une variable locale
                    408: 
                    409:            // Si le niveau de la dernière variable de même nom est
                    410:            // supérieur au niveau de la variable locale que l'on veut
                    411:            // enregistrer dans la liste, cette liste est incohérente.
                    412: 
                    413:            BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
                    414:                    (*s_variable).niveau,
                    415:                    printf("Variable=\"%s\"\n", (*s_variable).nom));
                    416: 
                    417:            // On ajoute la variable à la liste existante.
                    418: 
                    419:            (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
                    420:            (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
                    421:                    .precedent;
1.28      bertrand  422:            (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33      bertrand  423:            (*l_nouvelle_variable).noeud = l_variable_courante;
1.25      bertrand  424:            (*(*(*l_variable_courante).feuille).precedent).suivant =
                    425:                    l_nouvelle_variable;
                    426:            (*(*l_variable_courante).feuille).precedent =
                    427:                    l_nouvelle_variable;
                    428:            (*l_variable_courante).feuille = l_nouvelle_variable;
                    429: 
                    430:            if (((*(*l_variable_courante).feuille).variable =
                    431:                    malloc(sizeof(struct_variable))) == NULL)
                    432:            { 
                    433:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    434:                return(d_erreur);
                    435:            }
                    436: 
                    437:            (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
                    438:                    = (*s_variable);
1.31      bertrand  439:            pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1       bertrand  440:        }
                    441:        else
                    442:        {
1.25      bertrand  443:            // Cas d'une variable globale (niveau 0 [définitions] ou 1
                    444:            // [variables globales])
                    445: 
                    446:            l_variable_candidate = (*l_variable_courante).feuille;
                    447: 
                    448:            do
                    449:            {
                    450:                // S'il y a déjà une variable de même niveau, la pile
                    451:                // est incohérente.
                    452: 
                    453:                BUG((*(*l_variable_candidate).variable).niveau ==
                    454:                        (*s_variable).niveau,
                    455:                        printf("Variable=\"%s\"\n", (*s_variable).nom));
                    456: 
                    457:                l_variable_candidate = (*l_variable_candidate).precedent;
                    458:            } while((l_variable_candidate != (*l_variable_courante).feuille) &&
                    459:                    ((*(*l_variable_candidate).variable).niveau <= 1));
                    460: 
1.34      bertrand  461:            BUG((*s_variable).niveau == 0,
                    462:                    uprintf("Attempt to create a level-0 variable!\n"));
                    463: 
1.25      bertrand  464:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
                    465:                    .niveau > 1)
                    466:            {
1.34      bertrand  467:                // La variable précédente est de niveau strictement supérieur
                    468:                // à 1. Il ne peut donc y avoir aucune variable de niveau
                    469:                // inférieur ou égal à 1 puisque la boucle est triée.
                    470:                // On insère donc directement la variable en queue.
1.25      bertrand  471:            }
                    472:            else
1.1       bertrand  473:            {
1.34      bertrand  474:                // Le niveau de la variable précédente dans la boucle est
                    475:                // inférieur ou égal à 1.
1.25      bertrand  476:                l_variable_candidate = (*(*l_variable_courante).feuille)
                    477:                        .precedent;
                    478:            }
                    479: 
                    480:            (*l_nouvelle_variable).suivant = l_variable_candidate;
                    481:            (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                    482:                    .precedent;
1.28      bertrand  483:            (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33      bertrand  484:            (*l_nouvelle_variable).noeud = l_variable_courante;
1.25      bertrand  485:            (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
                    486:            (*l_variable_candidate).precedent = l_nouvelle_variable;
                    487: 
1.34      bertrand  488:            // Si la variable suivant la variable que l'on vient d'insérer
                    489:            // dans la boucle est de niveau 0, la variable insérée est par
                    490:            // construction de niveau 1 et il convient de modifier le
                    491:            // pointeur de feuille pointant sur l'élément de plus haut niveau
                    492:            // de la boucle.
                    493: 
                    494:            if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
                    495:            {
                    496:                (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
                    497:            }
                    498: 
1.25      bertrand  499:            if (((*l_nouvelle_variable).variable =
                    500:                    malloc(sizeof(struct_variable))) == NULL)
                    501:            { 
                    502:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    503:                return(d_erreur);
                    504:            }
                    505: 
                    506:            (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31      bertrand  507:            pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1       bertrand  508:        }
1.25      bertrand  509:    }
                    510: 
                    511:    // Ajout de la variable nouvellement créée à la liste par niveaux.
                    512:    // Le pointeur contenu dans la structure de description du processus indique
                    513:    // toujours le plus haut niveau utilisé.
                    514: 
                    515:    if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
                    516:    {
                    517:        // Le niveau courant n'existe pas. Il est créé.
                    518: 
                    519:        if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
                    520:                == NULL)
                    521:        {
                    522:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    523:            return(d_erreur);
                    524:        }
                    525: 
                    526:        (*l_nouvelle_variable).suivant = l_nouvelle_variable;
                    527:        (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28      bertrand  528:        (*l_nouvelle_variable).noeud_pere = NULL;
1.31      bertrand  529:        (*l_nouvelle_variable).liste = NULL;
1.25      bertrand  530: 
                    531:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33      bertrand  532: 
                    533:        // Ajout de la variable en tête de la liste
                    534: 
                    535:        if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
                    536:        {
                    537:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    538:            return(d_erreur);
                    539:        }
                    540: 
                    541:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    542:                .l_liste_variables_par_niveau).liste;
                    543:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    544:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    545:                l_nouvel_element;
1.25      bertrand  546:    }
                    547:    else if ((*s_variable).niveau > (*((struct_variable *)
                    548:            (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
                    549:            .donnee)).niveau)
                    550:    {
                    551:        // Le niveau courant n'existe pas. Il est créé.
1.1       bertrand  552: 
1.25      bertrand  553:        if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
                    554:                == NULL)
1.1       bertrand  555:        {
                    556:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    557:            return(d_erreur);
                    558:        }
                    559: 
1.25      bertrand  560:        (*l_nouvelle_variable).suivant = (*s_etat_processus)
                    561:                .l_liste_variables_par_niveau;
                    562:        (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
                    563:                .l_liste_variables_par_niveau).precedent;
1.28      bertrand  564:        (*l_nouvelle_variable).noeud_pere = NULL;
1.31      bertrand  565:        (*l_nouvelle_variable).liste = NULL;
1.25      bertrand  566:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
                    567:                .suivant = l_nouvelle_variable;
1.33      bertrand  568:        (*(*s_etat_processus).l_liste_variables_par_niveau)
                    569:                .precedent = l_nouvelle_variable;
1.25      bertrand  570: 
                    571:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33      bertrand  572: 
                    573:        // Ajout de la variable en tête de la liste
                    574: 
                    575:        if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
                    576:        {
                    577:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    578:            return(d_erreur);
                    579:        }
                    580: 
                    581:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    582:                .l_liste_variables_par_niveau).liste;
                    583:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    584:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    585:                l_nouvel_element;
1.25      bertrand  586:    }
1.31      bertrand  587:    else if ((*s_variable).niveau <= 1)
1.25      bertrand  588:    {
1.33      bertrand  589:        // Création d'une variable de niveau 0 ou 1. Il convient de
                    590:        // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
                    591:        // regarde la position courante et les deux précédentes.
                    592: 
                    593:        l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
                    594:        niveau_acceptable = d_faux;
1.25      bertrand  595: 
1.33      bertrand  596:        for(i = 0; i <= 2; i++)
                    597:        {
                    598:            if ((*l_variable_candidate).liste == NULL)
                    599:            {
                    600:                continue;
                    601:            }
                    602: 
                    603:            if ((*((struct_variable *) (*(*l_variable_candidate)
                    604:                    .liste).donnee)).niveau == (*s_variable).niveau)
                    605:            {
                    606:                niveau_acceptable = d_vrai;
                    607:                break;
                    608:            }
                    609: 
                    610:            l_variable_candidate = (*l_variable_candidate).precedent;
                    611:        }
                    612: 
                    613:        if (niveau_acceptable == d_faux)
1.28      bertrand  614:        {
1.33      bertrand  615:            if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
                    616:                    == NULL)
                    617:            {
                    618:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    619:                return(d_erreur);
                    620:            }
                    621: 
                    622:            l_variable_candidate =
                    623:                    (*(*s_etat_processus).l_liste_variables_par_niveau)
                    624:                    .precedent;
                    625: 
                    626:            // On ne peut créer qu'une variable de niveau supérieur ou égal à
                    627:            // 1 lors de l'exécution normale d'un programme. Les variables
                    628:            // de niveau 0 sont créées à l'initialisation et relèvent du
                    629:            // cas précédent car il n'existe lors de leur création aucun
                    630:            // niveau non nul.
                    631: 
                    632:            BUG((*s_variable).niveau == 0,
                    633:                    uprintf("Attempt to create a level-0 variable!\n"));
                    634: 
                    635:            (*l_nouvelle_variable).suivant = l_variable_candidate;
                    636:            (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                    637:                    .precedent;
                    638:            (*l_nouvelle_variable).noeud_pere = NULL;
                    639:            (*l_nouvelle_variable).liste = NULL;
                    640:            (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
                    641:            (*l_variable_candidate).precedent = l_nouvelle_variable;
                    642: 
                    643:            l_variable_candidate = l_nouvelle_variable;
1.28      bertrand  644:        }
                    645: 
1.33      bertrand  646:        // Ajout de la variable en tête de la liste l_variable_candidate.
1.25      bertrand  647: 
1.33      bertrand  648:        if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
1.25      bertrand  649:        {
1.33      bertrand  650:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    651:            return(d_erreur);
1.25      bertrand  652:        }
                    653: 
1.33      bertrand  654:        (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
                    655:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    656:        (*l_variable_candidate).liste = l_nouvel_element;
1.25      bertrand  657:    }
1.33      bertrand  658:    else
                    659:    {
                    660:        // Ajout de la variable en tête de la liste
1.25      bertrand  661: 
1.33      bertrand  662:        if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
                    663:        {
                    664:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    665:            return(d_erreur);
                    666:        }
1.25      bertrand  667: 
1.33      bertrand  668:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    669:                .l_liste_variables_par_niveau).liste;
                    670:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    671:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    672:                l_nouvel_element;
1.1       bertrand  673:    }
                    674: 
1.25      bertrand  675:    return(d_absence_erreur);
                    676: }
                    677: 
1.31      bertrand  678: 
1.25      bertrand  679: logical1
                    680: creation_variable(struct_processus *s_etat_processus,
                    681:        struct_variable *s_variable,
                    682:        unsigned char autorisation_creation_variable_statique,
                    683:        unsigned char autorisation_creation_variable_partagee)
                    684: {
1.1       bertrand  685:    if ((*s_etat_processus).mode_execution_programme == 'Y')
                    686:    {
                    687:        (*s_variable).origine = 'P';
                    688:    }
                    689:    else
                    690:    {
                    691:        (*s_variable).origine = 'E';
                    692:    }
                    693: 
                    694:    if ((*s_variable).niveau == 0)
                    695:    {
                    696:        // Un point d'entrée de définition est verrouillé.
                    697: 
                    698:        if ((*s_variable).origine == 'P')
                    699:        {
                    700:            (*s_variable).variable_statique.adresse = 0;
                    701:            (*s_variable).variable_partagee.adresse = 0;
                    702:        }
                    703:        else
                    704:        {
                    705:            (*s_variable).variable_statique.pointeur = NULL;
                    706:            (*s_variable).variable_partagee.pointeur = NULL;
                    707:        }
                    708: 
                    709:        (*s_variable).variable_verrouillee = d_vrai;
                    710:    }
                    711:    else if ((*s_variable).niveau == 1)
                    712:    {
                    713:        // Une variable globale ne peut être statique.
                    714: 
                    715:        if ((*s_variable).origine == 'P')
                    716:        {
                    717:            (*s_variable).variable_statique.adresse = 0;
                    718:            (*s_variable).variable_partagee.adresse = 0;
                    719:        }
                    720:        else
                    721:        {
                    722:            (*s_variable).variable_statique.pointeur = NULL;
                    723:            (*s_variable).variable_partagee.pointeur = NULL;
                    724:        }
                    725: 
                    726:        (*s_variable).variable_verrouillee = d_faux;
                    727:    }
                    728:    else
                    729:    {
                    730:        // 0 -> variable volatile
                    731:        // adresse de création -> variable statique
                    732: 
                    733:        if (autorisation_creation_variable_statique == 'V')
                    734:        {
                    735:            if (autorisation_creation_variable_partagee == 'S')
                    736:            {
                    737:                // On force la création d'une variable partagée
                    738: 
                    739:                if ((*s_variable).origine == 'P')
                    740:                {
                    741:                    (*s_variable).variable_statique.adresse = 0;
                    742:                    (*s_variable).variable_partagee.adresse =
                    743:                            (*s_etat_processus).position_courante;
                    744:                }
                    745:                else
                    746:                {
                    747:                    (*s_variable).variable_statique.pointeur = NULL;
                    748:                    (*s_variable).variable_partagee.pointeur =
                    749:                            (*s_etat_processus).objet_courant;
                    750:                }
                    751:            }
                    752:            else
                    753:            {
                    754:                // On force la création d'une variable volatile
                    755: 
                    756:                if ((*s_variable).origine == 'P')
                    757:                {
                    758:                    (*s_variable).variable_statique.adresse = 0;
                    759:                    (*s_variable).variable_partagee.adresse = 0;
                    760:                }
                    761:                else
                    762:                {
                    763:                    (*s_variable).variable_statique.pointeur = NULL;
                    764:                    (*s_variable).variable_partagee.pointeur = NULL;
                    765:                }
                    766:            }
                    767:        }
                    768:        else
                    769:        {
                    770:            // On force la création d'une variable statique.
                    771: 
                    772:            if ((*s_variable).origine == 'P')
                    773:            {
                    774:                (*s_variable).variable_statique.adresse =
                    775:                        (*s_etat_processus).position_courante;
                    776:                (*s_variable).variable_partagee.adresse = 0;
                    777:            }
                    778:            else
                    779:            {
                    780:                (*s_variable).variable_statique.pointeur =
                    781:                        (*s_etat_processus).objet_courant;
                    782:                (*s_variable).variable_partagee.pointeur = 0;
                    783:            }
                    784:        }
                    785: 
                    786:        (*s_variable).variable_verrouillee = d_faux;
                    787:    }
                    788: 
                    789:    /*
1.25      bertrand  790:     * Recherche de la feuille correspondante dans l'arbre des variables.
                    791:     * Si cette feuille n'existe pas, elle est créée.
1.1       bertrand  792:     */
                    793: 
1.25      bertrand  794:    if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
                    795:    {
                    796:        return(d_erreur);
                    797:    }
                    798: 
                    799:    return(d_absence_erreur);
                    800: }
                    801: 
                    802: 
                    803: /*
                    804: ================================================================================
                    805:   Procédure de recherche d'une variable par son nom dans la base
                    806: ================================================================================
                    807:   Entrée :
                    808: --------------------------------------------------------------------------------
                    809:   Sortie :
                    810: --------------------------------------------------------------------------------
                    811:   Effets de bord : néant
                    812: ================================================================================
                    813: */
                    814: 
                    815: logical1
                    816: recherche_variable(struct_processus *s_etat_processus,
                    817:        unsigned char *nom_variable)
                    818: {
                    819:    int                         pointeur;
                    820: 
                    821:    struct_arbre_variables      *l_variable_courante;
                    822:    struct_liste_pile_systeme   *l_element_courant;
                    823: 
                    824:    unsigned char               *ptr;
                    825: 
                    826:    unsigned long               niveau_appel;
1.1       bertrand  827: 
1.25      bertrand  828:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand  829:    {
1.25      bertrand  830:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30      bertrand  831:        return(d_faux);
1.1       bertrand  832:    }
1.25      bertrand  833: 
1.28      bertrand  834:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25      bertrand  835:    ptr = nom_variable;
                    836: 
                    837:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand  838:    {
1.25      bertrand  839:        pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
                    840: 
                    841:        if (pointeur < 0)
                    842:        {
                    843:            // Caractère hors de l'alphabet des variables
1.30      bertrand  844: 
                    845:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    846:            return(d_faux);
1.25      bertrand  847:        }
                    848: 
1.28      bertrand  849:        if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1       bertrand  850:        {
1.25      bertrand  851:            // Le chemin de la variable candidate n'existe pas.
1.30      bertrand  852:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    853:            return(d_faux);
1.1       bertrand  854:        }
                    855: 
1.28      bertrand  856:        l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25      bertrand  857:        ptr++;
                    858:    }
                    859: 
                    860:    if ((*l_variable_courante).feuille != NULL)
                    861:    {
                    862:        // Il existe une pile de variables de même nom. Le sommet de la
                    863:        // pile est la variable de niveau le plus haut.
                    864: 
                    865:        l_element_courant = (*s_etat_processus).l_base_pile_systeme;
                    866: 
                    867:        if (l_element_courant == NULL)
1.12      bertrand  868:        {
1.25      bertrand  869:            // Problème : la pile système est vide !
                    870:            (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30      bertrand  871:            return(d_faux);
1.12      bertrand  872:        }
1.25      bertrand  873: 
                    874:        while((*l_element_courant).retour_definition != 'Y')
1.12      bertrand  875:        {
1.25      bertrand  876:            l_element_courant = (*l_element_courant).suivant;
1.12      bertrand  877: 
1.25      bertrand  878:            if (l_element_courant == NULL)
1.12      bertrand  879:            {
1.25      bertrand  880:                (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30      bertrand  881:                return(d_faux);
1.12      bertrand  882:            }
1.25      bertrand  883:        }
                    884: 
                    885:        niveau_appel = (*l_element_courant).niveau_courant;
1.12      bertrand  886: 
1.25      bertrand  887:        if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
                    888:        {
                    889:            // Une variable locale est accessible puisque créée dans la
                    890:            // fonction courante.
                    891: 
                    892:            (*s_etat_processus).pointeur_variable_courante =
                    893:                    (*(*l_variable_courante).feuille).variable;
                    894:            (*s_etat_processus).pointeur_feuille_courante =
                    895:                    (*l_variable_courante).feuille;
1.30      bertrand  896:            return(d_vrai);
1.25      bertrand  897:        }
                    898:        else
                    899:        {
                    900:            // Aucune variable locale n'est accessible depuis la fonction.
                    901:            // Dans ce cas, on prend la variable de niveau le plus bas
                    902:            // si ce niveau est inférieur ou égal à 1 (variable globale
                    903:            // ou fonction définie par l'utilisateur). Si le niveau de la
1.27      bertrand  904:            // plus ancienne variable est strictement supérieur à 1, il
1.25      bertrand  905:            // s'agit d'une variable locale inaccessible.
                    906: 
                    907:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
                    908:                    .niveau <= 1)
                    909:            {
                    910:                (*s_etat_processus).pointeur_variable_courante =
                    911:                        (*(*(*l_variable_courante).feuille).precedent).variable;
                    912:                (*s_etat_processus).pointeur_feuille_courante =
1.33      bertrand  913:                        (*(*l_variable_courante).feuille).precedent;
1.27      bertrand  914: 
                    915:                // S'il existe une variable de niveau 0 et une seconde de
                    916:                // niveau 1, la variable de niveau 0 (fonction) est masquée
                    917:                // par celle de niveau 1.
                    918: 
1.33      bertrand  919:                if (((*(*(*(*l_variable_courante).feuille).precedent)
                    920:                        .variable).niveau == 0) && ((*(*(*(*
                    921:                        (*l_variable_courante).feuille).precedent).precedent)
1.27      bertrand  922:                        .variable).niveau == 1))
                    923:                {
                    924:                    (*s_etat_processus).pointeur_variable_courante =
1.33      bertrand  925:                            (*(*(*(*l_variable_courante).feuille).precedent)
                    926:                            .precedent).variable;
                    927:                    (*s_etat_processus).pointeur_feuille_courante =
1.27      bertrand  928:                            (*(*(*l_variable_courante).feuille).precedent)
1.33      bertrand  929:                            .precedent;
1.27      bertrand  930:                }
                    931: 
1.30      bertrand  932:                return(d_vrai);
1.12      bertrand  933:            }
                    934:        }
1.1       bertrand  935:    }
                    936: 
1.30      bertrand  937:    (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    938:    return(d_faux);
1.1       bertrand  939: }
                    940: 
                    941: 
1.29      bertrand  942: logical1
                    943: recherche_variable_globale(struct_processus *s_etat_processus,
                    944:        unsigned char *nom)
                    945: {
                    946:    logical1            presence_variable;
                    947: 
                    948:    presence_variable = recherche_variable(s_etat_processus, nom);
                    949: 
                    950:    if (presence_variable == d_vrai)
                    951:    {
                    952:        switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
                    953:        {
                    954:            case 0:
                    955:            {
1.33      bertrand  956:                // La variable est une définition.
1.29      bertrand  957:                presence_variable = d_faux;
                    958:                break;
                    959:            }
                    960: 
                    961:            case 1:
                    962:            {
                    963:                break;
                    964:            }
                    965: 
                    966:            default:
                    967:            {
                    968:                if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
                    969:                        .precedent).variable).niveau == 1)
                    970:                {
                    971:                    (*s_etat_processus).pointeur_feuille_courante =
                    972:                            (*(*s_etat_processus).pointeur_feuille_courante)
                    973:                            .precedent;
                    974:                    (*s_etat_processus).pointeur_variable_courante =
                    975:                            (*(*s_etat_processus).pointeur_feuille_courante)
                    976:                            .variable;
                    977:                }
                    978:                else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
                    979:                        .precedent).precedent).variable).niveau == 1)
                    980:                {
                    981:                    (*s_etat_processus).pointeur_feuille_courante =
                    982:                            (*(*(*s_etat_processus).pointeur_feuille_courante)
                    983:                            .precedent).precedent;
                    984:                    (*s_etat_processus).pointeur_variable_courante =
                    985:                            (*(*s_etat_processus).pointeur_feuille_courante)
                    986:                            .variable;
                    987:                }
                    988:                else
                    989:                {
                    990:                    presence_variable = d_faux;
                    991:                }
                    992: 
                    993:                break;
                    994:            }
                    995:        }
                    996:    }
                    997: 
                    998:    if (presence_variable == d_vrai)
                    999:    {
                   1000:        if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
                   1001:        {
                   1002:            // La variable n'est pas globale, elle est partagée.
                   1003:            presence_variable = d_faux;
                   1004:            (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
                   1005:        }
                   1006:    }
                   1007: 
                   1008:    return(presence_variable);
                   1009: }
                   1010: 
                   1011: 
1.1       bertrand 1012: /*
                   1013: ================================================================================
                   1014:   Procédure de retrait d'une variable de la base
                   1015: ================================================================================
                   1016:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
                   1017:            les globales) ou strictement globale.
                   1018: --------------------------------------------------------------------------------
                   1019:   Sortie :
                   1020: --------------------------------------------------------------------------------
                   1021:   Effets de bord : néant
                   1022: ================================================================================
                   1023: */
                   1024: 
                   1025: logical1
                   1026: retrait_variable(struct_processus *s_etat_processus,
                   1027:        unsigned char *nom_variable, unsigned char type)
                   1028: {
1.28      bertrand 1029:    logical1                    erreur;
1.34      bertrand 1030:    logical1                    variable_supprimee;
1.28      bertrand 1031: 
                   1032:    struct_arbre_variables      *s_arbre_a_supprimer;
                   1033:    struct_arbre_variables      *s_arbre_courant;
                   1034: 
                   1035:    struct_liste_chainee        *l_element_courant;
                   1036:    struct_liste_chainee        *l_element_precedent;
                   1037: 
                   1038:    struct_liste_variables      *variable_a_supprimer;
                   1039:    struct_liste_variables      *variables_par_niveau;
                   1040: 
                   1041:    unsigned long               niveau;
1.1       bertrand 1042: 
1.36    ! bertrand 1043:    (*s_etat_processus).niveau_supprime = d_faux;
        !          1044: 
1.1       bertrand 1045:    if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
                   1046:    {
1.25      bertrand 1047:        // Une variable correspondant au nom recherché est accessible.
                   1048: 
1.1       bertrand 1049:        if (type == 'G')
                   1050:        {
1.25      bertrand 1051:            if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
                   1052:            {
                   1053:                // La variable obtenue est une variable locale. il faut
                   1054:                // s'assurer qu'il existe une variable de niveau 1 de même
                   1055:                // nom sur la feuille.
                   1056: 
1.27      bertrand 1057:                if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
                   1058:                        .precedent).variable).niveau <= 1)
1.1       bertrand 1059:                {
1.27      bertrand 1060:                    (*s_etat_processus).pointeur_feuille_courante =
                   1061:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1062:                            .precedent;
                   1063:                    (*s_etat_processus).pointeur_variable_courante =
                   1064:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1065:                            .variable;
                   1066: 
                   1067:                    // Si la variable retournée est de niveau 0, on regarde
                   1068:                    // un peu plus loin si une variable de niveau 1 existe.
                   1069: 
                   1070:                    if (((*(*(*s_etat_processus).pointeur_feuille_courante)
                   1071:                            .variable).niveau == 0) &&
                   1072:                            ((*(*(*(*s_etat_processus)
                   1073:                            .pointeur_feuille_courante).precedent).variable)
                   1074:                            .niveau == 1))
1.1       bertrand 1075:                    {
1.27      bertrand 1076:                        (*s_etat_processus).pointeur_feuille_courante =
                   1077:                                (*(*s_etat_processus).pointeur_feuille_courante)
                   1078:                                .precedent;
                   1079:                        (*s_etat_processus).pointeur_variable_courante =
                   1080:                                (*(*s_etat_processus).pointeur_feuille_courante)
                   1081:                                .variable;
1.1       bertrand 1082:                    }
                   1083:                }
1.27      bertrand 1084:                else
                   1085:                {
                   1086:                    // Aucune variable globale (niveau 1) n'existe.
1.1       bertrand 1087: 
1.27      bertrand 1088:                    erreur = d_erreur;
                   1089:                    (*s_etat_processus).erreur_execution =
                   1090:                            d_ex_variable_non_definie;
                   1091:                    return(erreur);
                   1092:                }
1.1       bertrand 1093:            }
                   1094: 
1.27      bertrand 1095:            if ((*(*s_etat_processus).pointeur_variable_courante)
1.1       bertrand 1096:                    .variable_verrouillee == d_vrai)
                   1097:            {
                   1098:                erreur = d_erreur;
                   1099:                (*s_etat_processus).erreur_execution =
                   1100:                        d_ex_variable_verrouillee;
1.28      bertrand 1101:                return(erreur);
1.1       bertrand 1102:            }
                   1103:        }
                   1104: 
1.27      bertrand 1105:        // Suppression de la variable de la liste.
                   1106:        // Deux cas peuvent survenir :
                   1107:        // 1/ les pointeurs sur la variable et la variable suivante
                   1108:        // sont identiques et on supprime la variable ainsi que la feuille
                   1109:        // associée ;
                   1110:        // 2/ ces deux pointeurs sont différents et se contente de retirer
                   1111:        // la structure décrivant la variable.
1.1       bertrand 1112: 
1.28      bertrand 1113:        if ((*s_etat_processus).pointeur_feuille_courante ==
                   1114:                (*(*s_etat_processus).pointeur_feuille_courante).suivant)
                   1115:        {
                   1116:            // Cas 1 :
                   1117:            // On retire la variable du noeud en décrémentant le nombre
                   1118:            // de feuilles de ce noeud. Si le nombre de feuilles du noeud
                   1119:            // est nul, on retire les noeuds récursivement jusqu'à obtenir
                   1120:            // un nombre non nul de feuilles utilisées (ou la racine des
                   1121:            // variables).
                   1122: 
                   1123:            variable_a_supprimer = (*s_etat_processus)
                   1124:                    .pointeur_feuille_courante;
1.34      bertrand 1125:            //s_arbre_courant = (*variable_a_supprimer).noeud_pere;
                   1126:            s_arbre_courant = (*variable_a_supprimer).noeud;
1.28      bertrand 1127:            BUG((*s_arbre_courant).noeuds_utilises == 0,
                   1128:                    uprintf("Freed node !\n"));
                   1129:            (*s_arbre_courant).noeuds_utilises--;
1.1       bertrand 1130: 
1.34      bertrand 1131:            (*((*(*variable_a_supprimer).noeud_pere).noeuds
                   1132:                    [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                   1133:                    .feuille = NULL;
                   1134: 
1.28      bertrand 1135:            while((*s_arbre_courant).noeuds_utilises == 0)
                   1136:            {
                   1137:                s_arbre_a_supprimer = s_arbre_courant;
                   1138:                s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1       bertrand 1139: 
1.28      bertrand 1140:                if (s_arbre_courant == NULL)
                   1141:                {
1.31      bertrand 1142:                    free((*s_arbre_a_supprimer).noeuds);
                   1143:                    free(s_arbre_a_supprimer);
1.34      bertrand 1144: 
                   1145:                    (*s_etat_processus).s_arbre_variables = NULL;
1.28      bertrand 1146:                    break;
                   1147:                }
                   1148: 
1.31      bertrand 1149:                // s_arbre_a_supprimer contient la structure de feuille qui
                   1150:                // vient d'être libérée. Il s'agit maintenant
                   1151:                // d'annuler le pointeur dans le tableau noeuds de la structure
                   1152:                // pointée par noeud_pere, soit s_arbre_courant.
                   1153: 
                   1154:                BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
                   1155:                        uprintf("Invalid pointer !\n"));
                   1156:                (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
                   1157:                        .indice_tableau_pere] = NULL;
                   1158: 
                   1159:                free((*s_arbre_a_supprimer).noeuds);
                   1160:                free(s_arbre_a_supprimer);
                   1161: 
1.28      bertrand 1162:                BUG((*s_arbre_courant).noeuds_utilises == 0,
                   1163:                        uprintf("Freed node !\n"));
                   1164:                (*s_arbre_courant).noeuds_utilises--;
                   1165:            }
                   1166:        }
                   1167:        else
1.1       bertrand 1168:        {
1.28      bertrand 1169:            // Cas 2 :
                   1170:            // On retire la variable de la liste.
                   1171: 
                   1172:            variable_a_supprimer = (*s_etat_processus)
                   1173:                    .pointeur_feuille_courante;
                   1174: 
                   1175:            (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
                   1176:                    .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
                   1177:                    .suivant;
                   1178:            (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
                   1179:                    .precedent = (*(*s_etat_processus)
                   1180:                    .pointeur_feuille_courante).precedent;
1.32      bertrand 1181: 
1.33      bertrand 1182:            // Mise à jour du pointeur dans l'arbre des variables. Cette
                   1183:            // mise à jour n'est nécessaire que dans le cas où la variable
                   1184:            // supprimée est en tête de la liste.
                   1185: 
                   1186:            if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
                   1187:                    .noeuds[(*(*variable_a_supprimer).noeud)
                   1188:                    .indice_tableau_pere])).feuille)
                   1189:            {
                   1190:                (*((*(*variable_a_supprimer).noeud_pere).noeuds
                   1191:                        [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                   1192:                        .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
                   1193:                        .noeuds[(*(*variable_a_supprimer).noeud)
                   1194:                        .indice_tableau_pere])).feuille).suivant;
                   1195:            }
                   1196: 
                   1197:            (*s_etat_processus).pointeur_feuille_courante =
                   1198:                    (*(*s_etat_processus).pointeur_feuille_courante).suivant;
                   1199:            (*s_etat_processus).pointeur_variable_courante =
                   1200:                    (*(*s_etat_processus).pointeur_feuille_courante).variable;
1.1       bertrand 1201:        }
                   1202: 
1.28      bertrand 1203:        // Dans tous les cas, on retire la variable de la liste des variables
                   1204:        // par niveau.
                   1205: 
                   1206:        niveau = (*(*variable_a_supprimer).variable).niveau;
                   1207:        variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1.34      bertrand 1208:        variable_supprimee = d_faux;
1.28      bertrand 1209: 
1.31      bertrand 1210:        if (variables_par_niveau != NULL)
1.28      bertrand 1211:        {
1.31      bertrand 1212:            do
                   1213:            {
                   1214:                l_element_courant = (*variables_par_niveau).liste;
1.28      bertrand 1215: 
1.31      bertrand 1216:                if (l_element_courant != NULL)
1.28      bertrand 1217:                {
1.31      bertrand 1218:                    if ((*((struct_variable *) (*l_element_courant).donnee))
                   1219:                            .niveau == niveau)
                   1220:                    {
                   1221:                        // On parcourt le bon niveau.
1.28      bertrand 1222: 
1.31      bertrand 1223:                        l_element_precedent = NULL;
1.28      bertrand 1224: 
1.31      bertrand 1225:                        while(l_element_courant != NULL)
1.28      bertrand 1226:                        {
1.31      bertrand 1227:                            // Tant que l_element_courant est non nul, il reste
                   1228:                            // des variables à explorer dans le niveau courant.
1.28      bertrand 1229: 
1.31      bertrand 1230:                            if ((*l_element_courant).donnee ==
                   1231:                                    (void *) (*variable_a_supprimer).variable)
1.28      bertrand 1232:                            {
1.31      bertrand 1233:                                // On a trouvé la variable à supprimer.
                   1234: 
                   1235:                                if (l_element_precedent == NULL)
                   1236:                                {
                   1237:                                    (*variables_par_niveau).liste =
                   1238:                                            (*l_element_courant).suivant;
                   1239:                                }
                   1240:                                else
                   1241:                                {
                   1242:                                    (*l_element_precedent).suivant =
                   1243:                                            (*l_element_courant).suivant;
                   1244:                                }
                   1245: 
                   1246:                                free(l_element_courant);
1.34      bertrand 1247: 
                   1248:                                if ((*variables_par_niveau).liste == NULL)
                   1249:                                {
1.36    ! bertrand 1250:                                    (*s_etat_processus).niveau_supprime =
        !          1251:                                            d_vrai;
        !          1252: 
1.34      bertrand 1253:                                    if ((*s_etat_processus)
                   1254:                                            .l_liste_variables_par_niveau
                   1255:                                            == variables_par_niveau)
                   1256:                                    {
                   1257:                                        // On retire l'élément de la liste
                   1258:                                        // pointé par
                   1259:                                        // l_liste_variable_par_niveau
                   1260: 
                   1261:                                        (*s_etat_processus)
                   1262:                                                .l_liste_variables_par_niveau =
                   1263:                                                (*variables_par_niveau).suivant;
                   1264:                                    }
                   1265: 
                   1266:                                    (*(*variables_par_niveau).precedent)
                   1267:                                            .suivant =
                   1268:                                            (*variables_par_niveau).suivant;
                   1269:                                    (*(*variables_par_niveau).suivant)
                   1270:                                            .precedent =
                   1271:                                            (*variables_par_niveau)
                   1272:                                            .precedent;
                   1273:                                    free(variables_par_niveau);
                   1274:                                }
                   1275: 
                   1276:                                variable_supprimee = d_vrai;
1.31      bertrand 1277:                                break;
1.28      bertrand 1278:                            }
1.31      bertrand 1279: 
                   1280:                            l_element_precedent = l_element_courant;
                   1281:                            l_element_courant = (*l_element_courant).suivant;
1.28      bertrand 1282:                        }
                   1283:                    }
                   1284:                }
                   1285: 
1.34      bertrand 1286:                if (variable_supprimee == d_vrai)
                   1287:                {
                   1288:                    break;
                   1289:                }
                   1290: 
1.31      bertrand 1291:                variables_par_niveau = (*variables_par_niveau).suivant;
                   1292: 
                   1293:            } while(variables_par_niveau != (*s_etat_processus)
                   1294:                    .l_liste_variables_par_niveau);
1.28      bertrand 1295:        }
                   1296: 
                   1297:        // Puis on libère le contenu de la variable.
                   1298: 
                   1299:        free((*(*variable_a_supprimer).variable).nom);
                   1300:        liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.32      bertrand 1301:        free((*variable_a_supprimer).variable);
1.33      bertrand 1302:        free(variable_a_supprimer);
1.28      bertrand 1303: 
1.1       bertrand 1304:        erreur = d_absence_erreur;
                   1305:    }
                   1306:    else
                   1307:    {
1.25      bertrand 1308:        // Aucune variable n'est accessible depuis le point courant du
                   1309:        // programme.
                   1310: 
1.1       bertrand 1311:        erreur = d_erreur;
                   1312:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                   1313:    }
                   1314: 
1.25      bertrand 1315:    return(erreur);
1.1       bertrand 1316: }
                   1317: 
                   1318: 
                   1319: /*
                   1320: ================================================================================
                   1321:   Procédure de retrait des variables de niveau strictement supérieur au
                   1322:   niveau courant
                   1323: ================================================================================
                   1324:   Entrée :
                   1325: --------------------------------------------------------------------------------
                   1326:   Sortie :
                   1327: --------------------------------------------------------------------------------
                   1328:   Effets de bord : néant
                   1329: ================================================================================
                   1330: */
                   1331: 
                   1332: logical1
                   1333: retrait_variable_par_niveau(struct_processus *s_etat_processus)
                   1334: {
1.31      bertrand 1335:    struct_liste_variables          *l_element_a_supprimer;
                   1336: 
1.28      bertrand 1337:    // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
                   1338:    // La tête de la pile contient toujours les variables de plus haut niveau
                   1339:    // créées.
1.1       bertrand 1340: 
1.28      bertrand 1341:    while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1       bertrand 1342:    {
1.28      bertrand 1343:        if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1       bertrand 1344:        {
1.28      bertrand 1345:            // Si le niveau ne contient aucune variable, on le détruit.
                   1346:            // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
                   1347:            // faire.
1.1       bertrand 1348:        }
                   1349:        else
                   1350:        {
1.28      bertrand 1351:            // Le niveau contient des variables.
                   1352: 
                   1353:            if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1354:                    .l_liste_variables_par_niveau).liste).donnee)).niveau
                   1355:                    <= (*s_etat_processus).niveau_courant)
1.1       bertrand 1356:            {
1.28      bertrand 1357:                // On a retiré de l'arbre des variables toutes les
                   1358:                // variables de niveau strictement supérieur au niveau
                   1359:                // courant.
1.1       bertrand 1360: 
1.28      bertrand 1361:                break;
1.1       bertrand 1362:            }
1.28      bertrand 1363: 
                   1364:            while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
                   1365:                    != NULL)
1.1       bertrand 1366:            {
1.34      bertrand 1367:                // Nécessaire car le pointeur sur la tête de la pile
                   1368:                // peut être modifié par retrait_variable().
1.28      bertrand 1369:                // Sauvegarde des variables statiques.
                   1370: 
                   1371:                if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1372:                        .l_liste_variables_par_niveau).liste).donnee)).origine
                   1373:                        == 'P')
1.1       bertrand 1374:                {
1.28      bertrand 1375:                    if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1376:                            .l_liste_variables_par_niveau).liste).donnee))
                   1377:                            .variable_statique.adresse != 0)
1.1       bertrand 1378:                    {
1.28      bertrand 1379:                        if (recherche_variable_statique(s_etat_processus,
                   1380:                                (*((struct_variable *) (*(*(*s_etat_processus)
                   1381:                                .l_liste_variables_par_niveau).liste).donnee))
                   1382:                                .nom, (*((struct_variable *)
                   1383:                                (*(*(*s_etat_processus)
                   1384:                                .l_liste_variables_par_niveau).liste).donnee))
                   1385:                                .variable_statique, ((*s_etat_processus)
                   1386:                                .mode_execution_programme
                   1387:                                 == 'Y') ? 'P' : 'E') == d_vrai)
                   1388:                        {
                   1389:                            (*s_etat_processus).s_liste_variables_statiques
                   1390:                                    [(*s_etat_processus)
                   1391:                                    .position_variable_statique_courante]
                   1392:                                    .objet = (*((struct_variable *)
                   1393:                                    (*(*(*s_etat_processus)
                   1394:                                    .l_liste_variables_par_niveau).liste)
                   1395:                                    .donnee)).objet;
                   1396:                        }
                   1397:                        else
                   1398:                        {
                   1399:                            (*s_etat_processus).erreur_systeme =
                   1400:                                    d_es_variable_introuvable;
                   1401:                        }
                   1402: 
                   1403:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1404:                                .l_liste_variables_par_niveau).liste).donnee))
                   1405:                                .objet = NULL;
1.1       bertrand 1406:                    }
1.28      bertrand 1407:                }
                   1408:                else
                   1409:                {
                   1410:                    if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1411:                            .l_liste_variables_par_niveau).liste).donnee))
                   1412:                            .variable_statique.pointeur != NULL)
1.1       bertrand 1413:                    {
1.28      bertrand 1414:                        /*
                   1415:                         * Gestion des variables statiques
                   1416:                         */
                   1417: 
                   1418:                        if (recherche_variable_statique(s_etat_processus,
                   1419:                                (*((struct_variable *) (*(*(*s_etat_processus)
                   1420:                                .l_liste_variables_par_niveau).liste).donnee))
                   1421:                                .nom, (*((struct_variable *)
                   1422:                                (*(*(*s_etat_processus)
                   1423:                                .l_liste_variables_par_niveau).liste).donnee))
                   1424:                                .variable_statique, ((*s_etat_processus)
                   1425:                                .mode_execution_programme
                   1426:                                 == 'Y') ? 'P' : 'E') == d_vrai)
                   1427:                        {
                   1428:                            (*s_etat_processus).s_liste_variables_statiques
                   1429:                                    [(*s_etat_processus)
                   1430:                                    .position_variable_statique_courante]
                   1431:                                    .objet = (*((struct_variable *)
                   1432:                                    (*(*(*s_etat_processus)
                   1433:                                    .l_liste_variables_par_niveau).liste)
                   1434:                                    .donnee)).objet;
                   1435:                        }
                   1436:                        else
                   1437:                        {
                   1438:                            (*s_etat_processus).erreur_systeme =
                   1439:                                    d_es_variable_introuvable;
                   1440:                            return(d_erreur);
                   1441:                        }
                   1442: 
                   1443:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1444:                                .l_liste_variables_par_niveau).liste).donnee))
                   1445:                                .objet = NULL;
1.1       bertrand 1446:                    }
1.28      bertrand 1447:                }
1.1       bertrand 1448: 
1.28      bertrand 1449:                if (retrait_variable(s_etat_processus,
                   1450:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1451:                        .l_liste_variables_par_niveau).liste).donnee)).nom,
                   1452:                        'L') == d_erreur)
                   1453:                {
                   1454:                    return(d_erreur);
1.1       bertrand 1455:                }
1.34      bertrand 1456: 
                   1457:                if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1458:                        .l_liste_variables_par_niveau).liste).donnee)).niveau
                   1459:                        <= (*s_etat_processus).niveau_courant)
                   1460:                {
                   1461:                    // On a retiré de l'arbre des variables toutes les
                   1462:                    // variables de niveau strictement supérieur au niveau
                   1463:                    // courant.
                   1464: 
                   1465:                    return(d_absence_erreur);
                   1466:                }
1.1       bertrand 1467:            }
                   1468:        }
                   1469: 
1.31      bertrand 1470:        // On retire l'élément de la liste doublement chaînée et circulaire.
                   1471: 
                   1472:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
                   1473:                = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
                   1474:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
                   1475:                = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
                   1476: 
                   1477:        l_element_a_supprimer = (*s_etat_processus)
                   1478:                .l_liste_variables_par_niveau;
                   1479:        (*s_etat_processus).l_liste_variables_par_niveau =
                   1480:                (*l_element_a_supprimer).suivant;
                   1481:        free(l_element_a_supprimer);
1.1       bertrand 1482:    }
                   1483: 
                   1484:    return(d_absence_erreur);
                   1485: }
                   1486: 
1.23      bertrand 1487: 
                   1488: /*
                   1489: ================================================================================
1.24      bertrand 1490:   Procédure de retrait des toutes les variables locales et globales
                   1491: ================================================================================
                   1492:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
                   1493:            de niveau 0)
                   1494: --------------------------------------------------------------------------------
                   1495:   Sortie :
                   1496: --------------------------------------------------------------------------------
                   1497:   Effets de bord : néant
                   1498: ================================================================================
                   1499: */
                   1500: 
                   1501: void
                   1502: liberation_arbre_variables(struct_processus *s_etat_processus,
                   1503:        struct_arbre_variables *arbre, logical1 retrait_definitions)
                   1504: {
                   1505:    int                     i;
                   1506: 
1.28      bertrand 1507:    struct_liste_chainee    *l_element_courant_liste;
                   1508:    struct_liste_chainee    *l_element_suivant_liste;
                   1509: 
                   1510:    struct_liste_variables  *l_element_courant;
                   1511:    struct_liste_variables  *l_element_suivant;
                   1512: 
                   1513:    // Libération de l'arbre des variables. Le contenu des variables n'est
                   1514:    // pas détruit par cette opération, il sera détruit lors de la libération
                   1515:    // de la liste des variables par niveau.
1.24      bertrand 1516: 
1.34      bertrand 1517:    if (arbre == NULL)
                   1518:    {
                   1519:        return;
                   1520:    }
                   1521: 
1.31      bertrand 1522:    l_element_courant = (*arbre).feuille;
                   1523: 
                   1524:    if (l_element_courant != NULL)
                   1525:    {
                   1526:        do
                   1527:        {
                   1528:            l_element_suivant = (*l_element_courant).suivant;
                   1529:            free(l_element_courant);
                   1530:            l_element_courant = l_element_suivant;
                   1531:        } while(l_element_courant != (*arbre).feuille);
                   1532:    }
                   1533: 
1.24      bertrand 1534:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1535:    {
1.28      bertrand 1536:        if ((*arbre).noeuds[i] != NULL)
1.24      bertrand 1537:        {
1.28      bertrand 1538:            liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
                   1539:                    retrait_definitions);
                   1540:        }
                   1541:    }
                   1542: 
                   1543:    // Suppression de la liste des variables par niveau.
                   1544: 
                   1545:    if (arbre == (*s_etat_processus).s_arbre_variables)
                   1546:    {
                   1547:        l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
                   1548: 
1.31      bertrand 1549:        if (l_element_courant != NULL)
1.28      bertrand 1550:        {
1.31      bertrand 1551:            do
                   1552:            {
                   1553:                l_element_courant_liste = (*l_element_courant).liste;
1.24      bertrand 1554: 
1.31      bertrand 1555:                while(l_element_courant_liste != NULL)
1.24      bertrand 1556:                {
1.31      bertrand 1557:                    if ((retrait_definitions == d_vrai) ||
                   1558:                            ((*((struct_variable *) (*l_element_courant_liste)
                   1559:                            .donnee)).niveau >= 1))
                   1560:                    {
                   1561:                        liberation(s_etat_processus, (*((struct_variable *)
                   1562:                                (*l_element_courant_liste).donnee)).objet);
                   1563:                        free((*((struct_variable *) (*l_element_courant_liste)
                   1564:                                .donnee)).nom);
                   1565:                        free((*l_element_courant_liste).donnee);
                   1566:                    }
                   1567: 
                   1568:                    l_element_suivant_liste =
                   1569:                            (*l_element_courant_liste).suivant;
                   1570:                    free(l_element_courant_liste);
                   1571:                    l_element_courant_liste = l_element_suivant_liste;
1.24      bertrand 1572:                }
                   1573: 
1.31      bertrand 1574:                l_element_suivant = (*l_element_courant).suivant;
                   1575:                free(l_element_courant);
                   1576:                l_element_courant = l_element_suivant;
                   1577:            } while(l_element_courant != (*s_etat_processus)
                   1578:                    .l_liste_variables_par_niveau);
1.24      bertrand 1579:        }
                   1580:    }
                   1581: 
1.28      bertrand 1582:    free((*arbre).noeuds);
1.24      bertrand 1583:    free(arbre);
                   1584: 
                   1585:    return;
                   1586: }
                   1587: 
1.28      bertrand 1588: 
1.24      bertrand 1589: /*
                   1590: ================================================================================
1.33      bertrand 1591:   Procédure renvoyant les variables dans un tableau
                   1592: ================================================================================
                   1593:   Entrée :
                   1594: --------------------------------------------------------------------------------
                   1595:   Sortie :
                   1596: --------------------------------------------------------------------------------
                   1597:   Effets de bord : néant
                   1598: ================================================================================
                   1599: */
                   1600: 
                   1601: int
                   1602: nombre_variables(struct_processus *s_etat_processus,
                   1603:        struct_arbre_variables *l_element_courant)
                   1604: {
                   1605:    int                     i;
                   1606:    int                     n;
                   1607: 
                   1608:    struct_liste_variables  *l_variable;
                   1609: 
                   1610:    n = 0;
                   1611: 
                   1612:    if ((*l_element_courant).feuille != NULL)
                   1613:    {
                   1614:        l_variable = (*l_element_courant).feuille;
                   1615: 
                   1616:        do
                   1617:        {
                   1618:            n++;
                   1619:            l_variable = (*l_variable).suivant;
                   1620:        } while(l_variable != (*l_element_courant).feuille);
                   1621:    }
                   1622: 
                   1623:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1624:    {
                   1625:        if ((*l_element_courant).noeuds[i] != NULL)
                   1626:        {
                   1627:            n += nombre_variables(s_etat_processus,
                   1628:                    (*l_element_courant).noeuds[i]);
                   1629:        }
                   1630:    }
                   1631: 
                   1632:    return(n);
                   1633: }
                   1634: 
                   1635: int
                   1636: liste_variables(struct_processus *s_etat_processus,
                   1637:        struct_tableau_variables *tableau, int position,
                   1638:        struct_arbre_variables *l_element_courant)
                   1639: {
                   1640:    int                     i;
                   1641: 
                   1642:    struct_liste_variables  *l_variable;
                   1643: 
                   1644:    if ((*l_element_courant).feuille != NULL)
                   1645:    {
                   1646:        l_variable = (*l_element_courant).feuille;
                   1647: 
                   1648:        do
                   1649:        {
                   1650:            tableau[position].origine = (*(*l_variable).variable).origine;
                   1651:            tableau[position].nom = (*(*l_variable).variable).nom;
                   1652:            tableau[position].niveau = (*(*l_variable).variable).niveau;
                   1653:            tableau[position].objet = (*(*l_variable).variable).objet;
                   1654:            tableau[position].variable_verrouillee =
                   1655:                    (*(*l_variable).variable).variable_verrouillee;
                   1656:            tableau[position].variable_statique =
                   1657:                    (*(*l_variable).variable).variable_statique;
                   1658:            tableau[position].variable_partagee =
                   1659:                    (*(*l_variable).variable).variable_partagee;
                   1660: 
                   1661:            position++;
                   1662:            l_variable = (*l_variable).suivant;
                   1663:        } while(l_variable != (*l_element_courant).feuille);
                   1664:    }
                   1665: 
                   1666:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1667:    {
                   1668:        if ((*l_element_courant).noeuds[i] != NULL)
                   1669:        {
                   1670:            position = liste_variables(s_etat_processus,
                   1671:                    tableau, position, (*l_element_courant).noeuds[i]);
                   1672:        }
                   1673:    }
                   1674: 
                   1675:    return(position);
                   1676: }
                   1677: 
                   1678: /*
                   1679: ================================================================================
1.23      bertrand 1680:   Procédure de copie de l'arbre des variables
                   1681: ================================================================================
                   1682:   Entrée :
                   1683: --------------------------------------------------------------------------------
                   1684:   Sortie :
                   1685: --------------------------------------------------------------------------------
                   1686:   Effets de bord : néant
                   1687: ================================================================================
                   1688: */
                   1689: 
                   1690: struct_arbre_variables *
                   1691: copie_arbre_variables(struct_processus *s_etat_processus)
                   1692: {
                   1693:    // Les définitions sont partagées entre tous les threads et ne sont pas
                   1694:    // copiées.
1.28      bertrand 1695:    //
                   1696:    // NB : on ne copie que les variables de niveaux 0 et 1, les autres
                   1697:    // variables locales étant masquées par le processus de création de thread
                   1698:    // ou de processus, elles sont inaccessibles.
                   1699: 
                   1700:    BUG(1, uprintf("Oops !\n"));
1.23      bertrand 1701: 
                   1702:    return(d_absence_erreur);
                   1703: }
                   1704: 
                   1705: 
                   1706: /*
                   1707: ================================================================================
                   1708:   Procédure d'initialisation de la table de correspondance des variables
                   1709: ================================================================================
                   1710:   Entrée :
                   1711: --------------------------------------------------------------------------------
                   1712:   Sortie :
                   1713: --------------------------------------------------------------------------------
                   1714:   Effets de bord : néant
                   1715: ================================================================================
                   1716: */
                   1717: 
                   1718: /*
                   1719:  * Caractères autorisés dans les instructions
                   1720:  *
                   1721:  * 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
                   1722:  * 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
                   1723:  * _
                   1724:  * 1 2 3 4 5 6 7 8 9 0
                   1725:  */
                   1726: 
                   1727: void
                   1728: initialisation_variables(struct_processus *s_etat_processus)
                   1729: {
                   1730:    int             decalage;
                   1731:    int             i;
                   1732:    int             longueur_tableau;
                   1733: 
                   1734:    unsigned char   caractere;
                   1735: 
                   1736:    // Récupération de la longueur d'un unsigned char
                   1737: 
                   1738:    longueur_tableau = 1;
                   1739:    decalage = 0;
                   1740:    caractere = 1;
                   1741: 
                   1742:    while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
                   1743:    {
                   1744:        decalage++;
                   1745:        longueur_tableau *= 2;
                   1746:    }
                   1747: 
                   1748:    if (((*s_etat_processus).pointeurs_caracteres_variables =
                   1749:            malloc(longueur_tableau * sizeof(int))) == NULL)
                   1750:    {
                   1751:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   1752:        return;
                   1753:    }
                   1754: 
                   1755:    for(i = 0; i < longueur_tableau; i++)
                   1756:    {
                   1757:        (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
                   1758:    }
                   1759: 
                   1760:    (*s_etat_processus).nombre_caracteres_variables = 0;
                   1761: 
                   1762: #define DECLARATION_CARACTERE(c) \
                   1763:        do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
                   1764:        (*s_etat_processus).nombre_caracteres_variables++; } while(0)
                   1765: 
                   1766:    DECLARATION_CARACTERE('A');
                   1767:    DECLARATION_CARACTERE('B');
                   1768:    DECLARATION_CARACTERE('C');
                   1769:    DECLARATION_CARACTERE('D');
                   1770:    DECLARATION_CARACTERE('E');
                   1771:    DECLARATION_CARACTERE('F');
                   1772:    DECLARATION_CARACTERE('G');
                   1773:    DECLARATION_CARACTERE('H');
                   1774:    DECLARATION_CARACTERE('I');
                   1775:    DECLARATION_CARACTERE('J');
                   1776:    DECLARATION_CARACTERE('K');
                   1777:    DECLARATION_CARACTERE('L');
                   1778:    DECLARATION_CARACTERE('M');
                   1779:    DECLARATION_CARACTERE('N');
                   1780:    DECLARATION_CARACTERE('O');
                   1781:    DECLARATION_CARACTERE('P');
                   1782:    DECLARATION_CARACTERE('Q');
                   1783:    DECLARATION_CARACTERE('R');
                   1784:    DECLARATION_CARACTERE('S');
                   1785:    DECLARATION_CARACTERE('T');
                   1786:    DECLARATION_CARACTERE('U');
                   1787:    DECLARATION_CARACTERE('V');
                   1788:    DECLARATION_CARACTERE('W');
                   1789:    DECLARATION_CARACTERE('X');
                   1790:    DECLARATION_CARACTERE('Y');
                   1791:    DECLARATION_CARACTERE('Z');
                   1792: 
                   1793:    DECLARATION_CARACTERE('a');
                   1794:    DECLARATION_CARACTERE('b');
                   1795:    DECLARATION_CARACTERE('c');
                   1796:    DECLARATION_CARACTERE('d');
                   1797:    DECLARATION_CARACTERE('e');
                   1798:    DECLARATION_CARACTERE('f');
                   1799:    DECLARATION_CARACTERE('g');
                   1800:    DECLARATION_CARACTERE('h');
                   1801:    DECLARATION_CARACTERE('i');
                   1802:    DECLARATION_CARACTERE('j');
                   1803:    DECLARATION_CARACTERE('k');
                   1804:    DECLARATION_CARACTERE('l');
                   1805:    DECLARATION_CARACTERE('m');
                   1806:    DECLARATION_CARACTERE('n');
                   1807:    DECLARATION_CARACTERE('o');
                   1808:    DECLARATION_CARACTERE('p');
                   1809:    DECLARATION_CARACTERE('q');
                   1810:    DECLARATION_CARACTERE('r');
                   1811:    DECLARATION_CARACTERE('s');
                   1812:    DECLARATION_CARACTERE('t');
                   1813:    DECLARATION_CARACTERE('u');
                   1814:    DECLARATION_CARACTERE('v');
                   1815:    DECLARATION_CARACTERE('w');
                   1816:    DECLARATION_CARACTERE('x');
                   1817:    DECLARATION_CARACTERE('y');
                   1818:    DECLARATION_CARACTERE('z');
                   1819: 
                   1820:    DECLARATION_CARACTERE('_');
                   1821: 
                   1822:    DECLARATION_CARACTERE('1');
                   1823:    DECLARATION_CARACTERE('2');
                   1824:    DECLARATION_CARACTERE('3');
                   1825:    DECLARATION_CARACTERE('4');
                   1826:    DECLARATION_CARACTERE('5');
                   1827:    DECLARATION_CARACTERE('6');
                   1828:    DECLARATION_CARACTERE('7');
                   1829:    DECLARATION_CARACTERE('8');
                   1830:    DECLARATION_CARACTERE('9');
                   1831:    DECLARATION_CARACTERE('0');
                   1832: #undef DECLARATION_CARACTERE
                   1833: 
                   1834:    return;
                   1835: }
1.25      bertrand 1836: 
1.1       bertrand 1837: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>