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

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

CVSweb interface <joel.bertrand@systella.fr>