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

1.1       bertrand    1: /*
                      2: ================================================================================
1.102   ! bertrand    3:   RPL/2 (R) version 4.1.28
1.100     bertrand    4:   Copyright (C) 1989-2017 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.40      bertrand  230:   Routine de gestion du cache mémoire sur l'arbre des variables
                    231: ================================================================================
                    232:   Entrée :
                    233: --------------------------------------------------------------------------------
                    234:   Sortie :
                    235: --------------------------------------------------------------------------------
                    236:   Effets de bords : néant
                    237: ================================================================================
                    238: */
                    239: 
1.61      bertrand  240: struct_arbre_variables *
1.40      bertrand  241: allocation_noeud(struct_processus *s_etat_processus)
                    242: {
                    243:    struct_arbre_variables          *objet;
                    244: 
                    245:    if ((*s_etat_processus).pointeur_variables_noeud > 0)
                    246:    {
                    247:        objet = (*s_etat_processus).variables_noeud
                    248:                [--(*s_etat_processus).pointeur_variables_noeud];
                    249:    }
                    250:    else
                    251:    {
                    252:        objet = malloc(sizeof(struct_arbre_variables));
                    253:    }
                    254: 
                    255:    return(objet);
                    256: }
                    257: 
                    258: static inline void
                    259: liberation_noeud(struct_processus *s_etat_processus,
                    260:        struct_arbre_variables *objet)
                    261: {
                    262:    if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE)
                    263:    {
                    264:        (*s_etat_processus).variables_noeud
                    265:                [(*s_etat_processus).pointeur_variables_noeud++] = objet;
                    266:    }
                    267:    else
                    268:    {
                    269:        free(objet);
                    270:    }
                    271: 
                    272:    return;
                    273: }
                    274: 
1.61      bertrand  275: struct_arbre_variables **
1.40      bertrand  276: allocation_tableau_noeuds(struct_processus *s_etat_processus)
                    277: {
                    278:    struct_arbre_variables          **objet;
                    279: 
                    280:    if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0)
                    281:    {
                    282:        objet = (*s_etat_processus).variables_tableau_noeuds
                    283:                [--(*s_etat_processus).pointeur_variables_tableau_noeuds];
                    284:    }
                    285:    else
                    286:    {
1.70      bertrand  287:        objet = malloc(((size_t) (*s_etat_processus)
                    288:                .nombre_caracteres_variables)
1.40      bertrand  289:                * sizeof(struct_arbre_variables *));
                    290:    }
                    291: 
                    292:    return(objet);
                    293: }
                    294: 
                    295: static inline void
                    296: liberation_tableau_noeuds(struct_processus *s_etat_processus,
                    297:        struct_arbre_variables **objet)
                    298: {
                    299:    if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
                    300:    {
                    301:        (*s_etat_processus).variables_tableau_noeuds
                    302:                [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
                    303:                objet;
                    304:    }
                    305:    else
                    306:    {
                    307:        free(objet);
                    308:    }
                    309: 
                    310:    return;
                    311: }
                    312: 
                    313: static inline struct_liste_variables *
                    314: allocation_feuille(struct_processus *s_etat_processus)
                    315: {
                    316:    struct_liste_variables          *objet;
                    317: 
                    318:    if ((*s_etat_processus).pointeur_variables_feuille > 0)
                    319:    {
                    320:        objet = (*s_etat_processus).variables_feuille
                    321:                [--(*s_etat_processus).pointeur_variables_feuille];
                    322:    }
                    323:    else
                    324:    {
                    325:        objet = malloc(sizeof(struct_liste_variables));
                    326:    }
                    327: 
                    328:    return(objet);
                    329: }
                    330: 
                    331: static inline void
                    332: liberation_feuille(struct_processus *s_etat_processus,
                    333:        struct_liste_variables *objet)
                    334: {
                    335:    if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
                    336:    {
                    337:        (*s_etat_processus).variables_feuille
                    338:                [(*s_etat_processus).pointeur_variables_feuille++] = objet;
                    339:    }
                    340:    else
                    341:    {
                    342:        free(objet);
                    343:    }
                    344: 
                    345:    return;
                    346: }
                    347: 
                    348: static inline struct_variable *
                    349: allocation_variable(struct_processus *s_etat_processus)
                    350: {
                    351:    struct_variable             *objet;
                    352: 
                    353:    if ((*s_etat_processus).pointeur_variables_variable > 0)
                    354:    {
                    355:        objet = (*s_etat_processus).variables_variable
                    356:                [--(*s_etat_processus).pointeur_variables_variable];
                    357:    }
                    358:    else
                    359:    {
                    360:        objet = malloc(sizeof(struct_variable));
                    361:    }
                    362: 
                    363:    return(objet);
                    364: }
                    365: 
                    366: static inline void
                    367: liberation_variable(struct_processus *s_etat_processus,
                    368:        struct_variable *objet)
                    369: {
                    370:    if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
                    371:    {
                    372:        (*s_etat_processus).variables_variable
                    373:                [(*s_etat_processus).pointeur_variables_variable++] = objet;
                    374:    }
                    375:    else
                    376:    {
                    377:        free(objet);
                    378:    }
                    379: 
                    380:    return;
                    381: }
                    382: 
                    383: 
                    384: /*
                    385: ================================================================================
1.1       bertrand  386:   Routine de création d'une nouvelle variable
1.33      bertrand  387: ================================================================================
                    388:   Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
                    389:   dans le cas 'v', la variable est volatile.
                    390:   dans le cas 's', elle est statique.
                    391:   Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
                    392:   dans le cas 'p', la variable est privée.
                    393:   dans le cas 's', elle est partagée.
1.1       bertrand  394: --------------------------------------------------------------------------------
                    395:   Sortie :
                    396: --------------------------------------------------------------------------------
                    397:   Effets de bords : néant
                    398: ================================================================================
                    399: */
                    400: 
1.25      bertrand  401: static logical1
                    402: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1       bertrand  403: {
1.25      bertrand  404:    int                         i;
                    405: 
1.33      bertrand  406:    logical1                    niveau_acceptable;
                    407: 
1.25      bertrand  408:    struct_liste_variables      *l_nouvelle_variable;
                    409:    struct_liste_variables      *l_variable_candidate;
1.33      bertrand  410: 
1.28      bertrand  411:    struct_arbre_variables      *l_variable_courante;
                    412:    struct_arbre_variables      *l_variable_precedente;
1.1       bertrand  413: 
1.25      bertrand  414:    struct_liste_chainee        *l_nouvel_element;
1.1       bertrand  415: 
1.25      bertrand  416:    unsigned char               *ptr;
1.1       bertrand  417: 
1.31      bertrand  418:    void                        *pointeur_variable_cree;
                    419: 
1.25      bertrand  420:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand  421:    {
1.25      bertrand  422:        if (((*s_etat_processus).s_arbre_variables =
1.40      bertrand  423:                    allocation_noeud(s_etat_processus)) == NULL)
1.25      bertrand  424:        {
                    425:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    426:            return(d_erreur);
                    427:        }
                    428: 
                    429:        (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
1.58      bertrand  430:        (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL;
1.25      bertrand  431:        (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31      bertrand  432:        (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28      bertrand  433:        (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1       bertrand  434: 
1.30      bertrand  435:        if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.60      bertrand  436:                allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.1       bertrand  437:        {
1.25      bertrand  438:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    439:            return(d_erreur);
                    440:        }
                    441: 
                    442:        for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    443:        {
1.28      bertrand  444:            (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25      bertrand  445:        }
                    446:    }
                    447: 
1.28      bertrand  448:    l_variable_precedente = NULL;
1.25      bertrand  449:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
                    450:    ptr = (*s_variable).nom;
                    451: 
                    452:    while((*ptr) != d_code_fin_chaine)
                    453:    {
                    454:        BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
1.40      bertrand  455:                uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
1.25      bertrand  456:                *ptr));
                    457: 
1.28      bertrand  458:        if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  459:                .pointeurs_caracteres_variables[*ptr]] == NULL)
                    460:        {
1.31      bertrand  461:            // Le noeud n'existe pas encore, on le crée et on le marque
                    462:            // comme utilisé dans la structure parente.
1.25      bertrand  463: 
1.28      bertrand  464:            if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  465:                    .pointeurs_caracteres_variables[*ptr]] =
1.40      bertrand  466:                    allocation_noeud(s_etat_processus)) == NULL)
1.25      bertrand  467:            {
                    468:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    469:                return(d_erreur);
                    470:            }
                    471: 
1.28      bertrand  472:            (*l_variable_courante).noeuds_utilises++;
1.31      bertrand  473: 
                    474:            // La feuille est par défaut vide et aucun élément du tableau noeuds
                    475:            // (les branches qui peuvent être issues de ce nouveau noeud)
                    476:            // n'est encore utilisée.
                    477: 
1.28      bertrand  478:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  479:                    .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28      bertrand  480:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.58      bertrand  481:                    .pointeurs_caracteres_variables[*ptr]]).feuille_statique
                    482:                    = NULL;
                    483:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25      bertrand  484:                    .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31      bertrand  485: 
                    486:            // Le champ noeud_pere de la structure créée pointe sur
                    487:            // la structure parente et l'indice tableau_pere correspond à la
                    488:            // position réelle dans le tableau noeuds[] de la structure parente
                    489:            // du noeud courant. Cette valeur sera utilisée lors de la
                    490:            // destruction du noeud pour annuler le pointeur contenu dans
                    491:            // le tableau noeuds[] de la structure parente.
                    492: 
1.28      bertrand  493:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    494:                    .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31      bertrand  495:                    l_variable_courante;
                    496:            (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    497:                    .pointeurs_caracteres_variables[*ptr]])
                    498:                    .indice_tableau_pere = (*s_etat_processus)
                    499:                    .pointeurs_caracteres_variables[*ptr];
                    500: 
                    501:            // Allocation du tableau noeuds[] et initialisation à zéro de
                    502:            // tous les pointeurs.
1.25      bertrand  503: 
1.28      bertrand  504:            if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
                    505:                    .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.40      bertrand  506:                    allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.25      bertrand  507:            {
                    508:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    509:                return(d_erreur);
                    510:            }
                    511: 
                    512:            for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    513:            {
1.28      bertrand  514:                (*(*l_variable_courante).noeuds[(*s_etat_processus)
                    515:                        .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                    516:                        = NULL;
1.25      bertrand  517:            }
                    518:        }
                    519: 
1.28      bertrand  520:        l_variable_precedente = l_variable_courante;
                    521:        l_variable_courante = (*l_variable_courante).noeuds
1.25      bertrand  522:                [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
                    523:        ptr++;
                    524:    }
                    525: 
                    526:    if ((*l_variable_courante).feuille == NULL)
                    527:    {
                    528:        // Aucune variable de même nom préexiste. On alloue le premier
                    529:        // élément de la liste doublement chaînée contenant toutes les
                    530:        // variables de même nom. Cette liste boucle en premier lieu sur
                    531:        // elle-même.
                    532: 
1.40      bertrand  533:        if (((*l_variable_courante).feuille = allocation_feuille(
                    534:                s_etat_processus)) == NULL)
1.25      bertrand  535:        {
                    536:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    537:            return(d_erreur);
                    538:        }
                    539: 
1.34      bertrand  540:        (*l_variable_courante).noeuds_utilises++;
                    541: 
1.25      bertrand  542:        (*(*l_variable_courante).feuille).suivant =
                    543:                (*l_variable_courante).feuille;
                    544:        (*(*l_variable_courante).feuille).precedent =
                    545:                (*l_variable_courante).feuille;
1.28      bertrand  546:        (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32      bertrand  547:        (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25      bertrand  548: 
                    549:        // Allocation de la variable sur l'élément de la liste.
                    550: 
                    551:        if (((*(*l_variable_courante).feuille).variable =
1.40      bertrand  552:                allocation_variable(s_etat_processus)) == NULL)
1.25      bertrand  553:        { 
                    554:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    555:            return(d_erreur);
                    556:        }
                    557: 
                    558:        (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
                    559:                (*s_variable);
1.31      bertrand  560:        pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25      bertrand  561:    }
                    562:    else
                    563:    {
1.40      bertrand  564:        if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.28      bertrand  565:                == NULL)
                    566:        {
                    567:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    568:            return(d_erreur);
                    569:        }
                    570: 
1.25      bertrand  571:        if ((*s_variable).niveau > 1)
                    572:        {
                    573:            // Cas d'une variable locale
                    574: 
                    575:            // Si le niveau de la dernière variable de même nom est
                    576:            // supérieur au niveau de la variable locale que l'on veut
                    577:            // enregistrer dans la liste, cette liste est incohérente.
                    578: 
                    579:            BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
                    580:                    (*s_variable).niveau,
1.40      bertrand  581:                    uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25      bertrand  582: 
                    583:            // On ajoute la variable à la liste existante.
                    584: 
                    585:            (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
                    586:            (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
                    587:                    .precedent;
1.28      bertrand  588:            (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33      bertrand  589:            (*l_nouvelle_variable).noeud = l_variable_courante;
1.25      bertrand  590:            (*(*(*l_variable_courante).feuille).precedent).suivant =
                    591:                    l_nouvelle_variable;
                    592:            (*(*l_variable_courante).feuille).precedent =
                    593:                    l_nouvelle_variable;
                    594:            (*l_variable_courante).feuille = l_nouvelle_variable;
                    595: 
                    596:            if (((*(*l_variable_courante).feuille).variable =
1.40      bertrand  597:                    allocation_variable(s_etat_processus)) == NULL)
1.25      bertrand  598:            { 
                    599:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    600:                return(d_erreur);
                    601:            }
                    602: 
                    603:            (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
                    604:                    = (*s_variable);
1.31      bertrand  605:            pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1       bertrand  606:        }
                    607:        else
                    608:        {
1.25      bertrand  609:            // Cas d'une variable globale (niveau 0 [définitions] ou 1
                    610:            // [variables globales])
                    611: 
                    612:            l_variable_candidate = (*l_variable_courante).feuille;
                    613: 
                    614:            do
                    615:            {
                    616:                // S'il y a déjà une variable de même niveau, la pile
                    617:                // est incohérente.
                    618: 
                    619:                BUG((*(*l_variable_candidate).variable).niveau ==
                    620:                        (*s_variable).niveau,
1.40      bertrand  621:                        uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25      bertrand  622: 
                    623:                l_variable_candidate = (*l_variable_candidate).precedent;
                    624:            } while((l_variable_candidate != (*l_variable_courante).feuille) &&
                    625:                    ((*(*l_variable_candidate).variable).niveau <= 1));
                    626: 
1.34      bertrand  627:            BUG((*s_variable).niveau == 0,
                    628:                    uprintf("Attempt to create a level-0 variable!\n"));
                    629: 
1.25      bertrand  630:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
                    631:                    .niveau > 1)
                    632:            {
1.34      bertrand  633:                // La variable précédente est de niveau strictement supérieur
                    634:                // à 1. Il ne peut donc y avoir aucune variable de niveau
                    635:                // inférieur ou égal à 1 puisque la boucle est triée.
                    636:                // On insère donc directement la variable en queue.
1.25      bertrand  637:            }
                    638:            else
1.1       bertrand  639:            {
1.34      bertrand  640:                // Le niveau de la variable précédente dans la boucle est
                    641:                // inférieur ou égal à 1.
1.25      bertrand  642:                l_variable_candidate = (*(*l_variable_courante).feuille)
                    643:                        .precedent;
                    644:            }
                    645: 
                    646:            (*l_nouvelle_variable).suivant = l_variable_candidate;
                    647:            (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                    648:                    .precedent;
1.28      bertrand  649:            (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33      bertrand  650:            (*l_nouvelle_variable).noeud = l_variable_courante;
1.25      bertrand  651:            (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
                    652:            (*l_variable_candidate).precedent = l_nouvelle_variable;
                    653: 
1.34      bertrand  654:            // Si la variable suivant la variable que l'on vient d'insérer
                    655:            // dans la boucle est de niveau 0, la variable insérée est par
                    656:            // construction de niveau 1 et il convient de modifier le
                    657:            // pointeur de feuille pointant sur l'élément de plus haut niveau
                    658:            // de la boucle.
                    659: 
                    660:            if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
                    661:            {
                    662:                (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
                    663:            }
                    664: 
1.25      bertrand  665:            if (((*l_nouvelle_variable).variable =
1.40      bertrand  666:                    allocation_variable(s_etat_processus)) == NULL)
1.25      bertrand  667:            { 
                    668:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    669:                return(d_erreur);
                    670:            }
                    671: 
                    672:            (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31      bertrand  673:            pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1       bertrand  674:        }
1.25      bertrand  675:    }
                    676: 
                    677:    // Ajout de la variable nouvellement créée à la liste par niveaux.
                    678:    // Le pointeur contenu dans la structure de description du processus indique
                    679:    // toujours le plus haut niveau utilisé.
                    680: 
                    681:    if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
                    682:    {
                    683:        // Le niveau courant n'existe pas. Il est créé.
                    684: 
1.40      bertrand  685:        if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25      bertrand  686:                == NULL)
                    687:        {
                    688:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    689:            return(d_erreur);
                    690:        }
                    691: 
                    692:        (*l_nouvelle_variable).suivant = l_nouvelle_variable;
                    693:        (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28      bertrand  694:        (*l_nouvelle_variable).noeud_pere = NULL;
1.31      bertrand  695:        (*l_nouvelle_variable).liste = NULL;
1.25      bertrand  696: 
                    697:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33      bertrand  698: 
                    699:        // Ajout de la variable en tête de la liste
                    700: 
1.40      bertrand  701:        if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33      bertrand  702:        {
                    703:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    704:            return(d_erreur);
                    705:        }
                    706: 
                    707:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    708:                .l_liste_variables_par_niveau).liste;
                    709:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    710:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    711:                l_nouvel_element;
1.25      bertrand  712:    }
                    713:    else if ((*s_variable).niveau > (*((struct_variable *)
                    714:            (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
                    715:            .donnee)).niveau)
                    716:    {
                    717:        // Le niveau courant n'existe pas. Il est créé.
1.1       bertrand  718: 
1.40      bertrand  719:        if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25      bertrand  720:                == NULL)
1.1       bertrand  721:        {
                    722:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    723:            return(d_erreur);
                    724:        }
                    725: 
1.25      bertrand  726:        (*l_nouvelle_variable).suivant = (*s_etat_processus)
                    727:                .l_liste_variables_par_niveau;
                    728:        (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
                    729:                .l_liste_variables_par_niveau).precedent;
1.28      bertrand  730:        (*l_nouvelle_variable).noeud_pere = NULL;
1.31      bertrand  731:        (*l_nouvelle_variable).liste = NULL;
1.25      bertrand  732:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
                    733:                .suivant = l_nouvelle_variable;
1.33      bertrand  734:        (*(*s_etat_processus).l_liste_variables_par_niveau)
                    735:                .precedent = l_nouvelle_variable;
1.25      bertrand  736: 
                    737:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33      bertrand  738: 
                    739:        // Ajout de la variable en tête de la liste
                    740: 
1.40      bertrand  741:        if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33      bertrand  742:        {
                    743:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    744:            return(d_erreur);
                    745:        }
                    746: 
                    747:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    748:                .l_liste_variables_par_niveau).liste;
                    749:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    750:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    751:                l_nouvel_element;
1.25      bertrand  752:    }
1.31      bertrand  753:    else if ((*s_variable).niveau <= 1)
1.25      bertrand  754:    {
1.33      bertrand  755:        // Création d'une variable de niveau 0 ou 1. Il convient de
                    756:        // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
                    757:        // regarde la position courante et les deux précédentes.
                    758: 
                    759:        l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
                    760:        niveau_acceptable = d_faux;
1.25      bertrand  761: 
1.33      bertrand  762:        for(i = 0; i <= 2; i++)
                    763:        {
                    764:            if ((*l_variable_candidate).liste == NULL)
                    765:            {
                    766:                continue;
                    767:            }
                    768: 
                    769:            if ((*((struct_variable *) (*(*l_variable_candidate)
                    770:                    .liste).donnee)).niveau == (*s_variable).niveau)
                    771:            {
                    772:                niveau_acceptable = d_vrai;
                    773:                break;
                    774:            }
                    775: 
                    776:            l_variable_candidate = (*l_variable_candidate).precedent;
                    777:        }
                    778: 
                    779:        if (niveau_acceptable == d_faux)
1.28      bertrand  780:        {
1.40      bertrand  781:            if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.33      bertrand  782:                    == NULL)
                    783:            {
                    784:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    785:                return(d_erreur);
                    786:            }
                    787: 
                    788:            l_variable_candidate =
                    789:                    (*(*s_etat_processus).l_liste_variables_par_niveau)
                    790:                    .precedent;
                    791: 
                    792:            // On ne peut créer qu'une variable de niveau supérieur ou égal à
                    793:            // 1 lors de l'exécution normale d'un programme. Les variables
                    794:            // de niveau 0 sont créées à l'initialisation et relèvent du
                    795:            // cas précédent car il n'existe lors de leur création aucun
                    796:            // niveau non nul.
                    797: 
                    798:            BUG((*s_variable).niveau == 0,
                    799:                    uprintf("Attempt to create a level-0 variable!\n"));
                    800: 
                    801:            (*l_nouvelle_variable).suivant = l_variable_candidate;
                    802:            (*l_nouvelle_variable).precedent = (*l_variable_candidate)
                    803:                    .precedent;
                    804:            (*l_nouvelle_variable).noeud_pere = NULL;
                    805:            (*l_nouvelle_variable).liste = NULL;
                    806:            (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
                    807:            (*l_variable_candidate).precedent = l_nouvelle_variable;
                    808: 
                    809:            l_variable_candidate = l_nouvelle_variable;
1.28      bertrand  810:        }
                    811: 
1.33      bertrand  812:        // Ajout de la variable en tête de la liste l_variable_candidate.
1.25      bertrand  813: 
1.40      bertrand  814:        if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.25      bertrand  815:        {
1.33      bertrand  816:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    817:            return(d_erreur);
1.25      bertrand  818:        }
                    819: 
1.33      bertrand  820:        (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
                    821:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    822:        (*l_variable_candidate).liste = l_nouvel_element;
1.25      bertrand  823:    }
1.33      bertrand  824:    else
                    825:    {
                    826:        // Ajout de la variable en tête de la liste
1.25      bertrand  827: 
1.40      bertrand  828:        if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33      bertrand  829:        {
                    830:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    831:            return(d_erreur);
                    832:        }
1.25      bertrand  833: 
1.33      bertrand  834:        (*l_nouvel_element).suivant = (*(*s_etat_processus)
                    835:                .l_liste_variables_par_niveau).liste;
                    836:        (*l_nouvel_element).donnee = pointeur_variable_cree;
                    837:        (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
                    838:                l_nouvel_element;
1.1       bertrand  839:    }
                    840: 
1.25      bertrand  841:    return(d_absence_erreur);
                    842: }
                    843: 
1.31      bertrand  844: 
1.25      bertrand  845: logical1
                    846: creation_variable(struct_processus *s_etat_processus,
                    847:        struct_variable *s_variable,
                    848:        unsigned char autorisation_creation_variable_statique,
                    849:        unsigned char autorisation_creation_variable_partagee)
                    850: {
1.1       bertrand  851:    if ((*s_etat_processus).mode_execution_programme == 'Y')
                    852:    {
                    853:        (*s_variable).origine = 'P';
                    854:    }
                    855:    else
                    856:    {
                    857:        (*s_variable).origine = 'E';
                    858:    }
                    859: 
                    860:    if ((*s_variable).niveau == 0)
                    861:    {
                    862:        // Un point d'entrée de définition est verrouillé.
                    863: 
                    864:        if ((*s_variable).origine == 'P')
                    865:        {
                    866:            (*s_variable).variable_statique.adresse = 0;
                    867:            (*s_variable).variable_partagee.adresse = 0;
                    868:        }
                    869:        else
                    870:        {
                    871:            (*s_variable).variable_statique.pointeur = NULL;
                    872:            (*s_variable).variable_partagee.pointeur = NULL;
                    873:        }
                    874: 
                    875:        (*s_variable).variable_verrouillee = d_vrai;
                    876:    }
                    877:    else if ((*s_variable).niveau == 1)
                    878:    {
                    879:        // Une variable globale ne peut être statique.
                    880: 
                    881:        if ((*s_variable).origine == 'P')
                    882:        {
                    883:            (*s_variable).variable_statique.adresse = 0;
                    884:            (*s_variable).variable_partagee.adresse = 0;
                    885:        }
                    886:        else
                    887:        {
                    888:            (*s_variable).variable_statique.pointeur = NULL;
                    889:            (*s_variable).variable_partagee.pointeur = NULL;
                    890:        }
                    891: 
                    892:        (*s_variable).variable_verrouillee = d_faux;
                    893:    }
                    894:    else
                    895:    {
                    896:        // 0 -> variable volatile
                    897:        // adresse de création -> variable statique
                    898: 
                    899:        if (autorisation_creation_variable_statique == 'V')
                    900:        {
                    901:            if (autorisation_creation_variable_partagee == 'S')
                    902:            {
                    903:                // On force la création d'une variable partagée
                    904: 
                    905:                if ((*s_variable).origine == 'P')
                    906:                {
                    907:                    (*s_variable).variable_statique.adresse = 0;
                    908:                    (*s_variable).variable_partagee.adresse =
                    909:                            (*s_etat_processus).position_courante;
                    910:                }
                    911:                else
                    912:                {
                    913:                    (*s_variable).variable_statique.pointeur = NULL;
                    914:                    (*s_variable).variable_partagee.pointeur =
                    915:                            (*s_etat_processus).objet_courant;
                    916:                }
                    917:            }
                    918:            else
                    919:            {
                    920:                // On force la création d'une variable volatile
                    921: 
                    922:                if ((*s_variable).origine == 'P')
                    923:                {
                    924:                    (*s_variable).variable_statique.adresse = 0;
                    925:                    (*s_variable).variable_partagee.adresse = 0;
                    926:                }
                    927:                else
                    928:                {
                    929:                    (*s_variable).variable_statique.pointeur = NULL;
                    930:                    (*s_variable).variable_partagee.pointeur = NULL;
                    931:                }
                    932:            }
                    933:        }
                    934:        else
                    935:        {
                    936:            // On force la création d'une variable statique.
                    937: 
                    938:            if ((*s_variable).origine == 'P')
                    939:            {
                    940:                (*s_variable).variable_statique.adresse =
                    941:                        (*s_etat_processus).position_courante;
                    942:                (*s_variable).variable_partagee.adresse = 0;
                    943:            }
                    944:            else
                    945:            {
                    946:                (*s_variable).variable_statique.pointeur =
                    947:                        (*s_etat_processus).objet_courant;
                    948:                (*s_variable).variable_partagee.pointeur = 0;
                    949:            }
                    950:        }
                    951: 
                    952:        (*s_variable).variable_verrouillee = d_faux;
                    953:    }
                    954: 
                    955:    /*
1.25      bertrand  956:     * Recherche de la feuille correspondante dans l'arbre des variables.
                    957:     * Si cette feuille n'existe pas, elle est créée.
1.1       bertrand  958:     */
                    959: 
1.25      bertrand  960:    if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
                    961:    {
                    962:        return(d_erreur);
                    963:    }
                    964: 
                    965:    return(d_absence_erreur);
                    966: }
                    967: 
                    968: 
                    969: /*
                    970: ================================================================================
                    971:   Procédure de recherche d'une variable par son nom dans la base
                    972: ================================================================================
                    973:   Entrée :
                    974: --------------------------------------------------------------------------------
                    975:   Sortie :
                    976: --------------------------------------------------------------------------------
                    977:   Effets de bord : néant
                    978: ================================================================================
                    979: */
                    980: 
                    981: logical1
                    982: recherche_variable(struct_processus *s_etat_processus,
                    983:        unsigned char *nom_variable)
                    984: {
                    985:    int                         pointeur;
                    986: 
                    987:    struct_arbre_variables      *l_variable_courante;
                    988:    struct_liste_pile_systeme   *l_element_courant;
                    989: 
                    990:    unsigned char               *ptr;
                    991: 
1.70      bertrand  992:    integer8                    niveau_appel;
1.1       bertrand  993: 
1.25      bertrand  994:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand  995:    {
1.25      bertrand  996:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30      bertrand  997:        return(d_faux);
1.1       bertrand  998:    }
1.25      bertrand  999: 
1.28      bertrand 1000:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25      bertrand 1001:    ptr = nom_variable;
                   1002: 
                   1003:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand 1004:    {
1.25      bertrand 1005:        pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
                   1006: 
                   1007:        if (pointeur < 0)
                   1008:        {
                   1009:            // Caractère hors de l'alphabet des variables
1.30      bertrand 1010: 
                   1011:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                   1012:            return(d_faux);
1.25      bertrand 1013:        }
                   1014: 
1.28      bertrand 1015:        if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1       bertrand 1016:        {
1.25      bertrand 1017:            // Le chemin de la variable candidate n'existe pas.
1.30      bertrand 1018:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                   1019:            return(d_faux);
1.1       bertrand 1020:        }
                   1021: 
1.28      bertrand 1022:        l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25      bertrand 1023:        ptr++;
                   1024:    }
                   1025: 
                   1026:    if ((*l_variable_courante).feuille != NULL)
                   1027:    {
                   1028:        // Il existe une pile de variables de même nom. Le sommet de la
                   1029:        // pile est la variable de niveau le plus haut.
                   1030: 
                   1031:        l_element_courant = (*s_etat_processus).l_base_pile_systeme;
                   1032: 
                   1033:        if (l_element_courant == NULL)
1.12      bertrand 1034:        {
1.25      bertrand 1035:            // Problème : la pile système est vide !
                   1036:            (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30      bertrand 1037:            return(d_faux);
1.12      bertrand 1038:        }
1.25      bertrand 1039: 
                   1040:        while((*l_element_courant).retour_definition != 'Y')
1.12      bertrand 1041:        {
1.25      bertrand 1042:            l_element_courant = (*l_element_courant).suivant;
1.12      bertrand 1043: 
1.25      bertrand 1044:            if (l_element_courant == NULL)
1.12      bertrand 1045:            {
1.25      bertrand 1046:                (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30      bertrand 1047:                return(d_faux);
1.12      bertrand 1048:            }
1.25      bertrand 1049:        }
                   1050: 
                   1051:        niveau_appel = (*l_element_courant).niveau_courant;
1.12      bertrand 1052: 
1.25      bertrand 1053:        if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
                   1054:        {
                   1055:            // Une variable locale est accessible puisque créée dans la
                   1056:            // fonction courante.
                   1057: 
                   1058:            (*s_etat_processus).pointeur_variable_courante =
                   1059:                    (*(*l_variable_courante).feuille).variable;
                   1060:            (*s_etat_processus).pointeur_feuille_courante =
                   1061:                    (*l_variable_courante).feuille;
1.30      bertrand 1062:            return(d_vrai);
1.25      bertrand 1063:        }
                   1064:        else
                   1065:        {
                   1066:            // Aucune variable locale n'est accessible depuis la fonction.
                   1067:            // Dans ce cas, on prend la variable de niveau le plus bas
                   1068:            // si ce niveau est inférieur ou égal à 1 (variable globale
                   1069:            // ou fonction définie par l'utilisateur). Si le niveau de la
1.27      bertrand 1070:            // plus ancienne variable est strictement supérieur à 1, il
1.25      bertrand 1071:            // s'agit d'une variable locale inaccessible.
                   1072: 
                   1073:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
                   1074:                    .niveau <= 1)
                   1075:            {
                   1076:                (*s_etat_processus).pointeur_variable_courante =
                   1077:                        (*(*(*l_variable_courante).feuille).precedent).variable;
                   1078:                (*s_etat_processus).pointeur_feuille_courante =
1.33      bertrand 1079:                        (*(*l_variable_courante).feuille).precedent;
1.27      bertrand 1080: 
                   1081:                // S'il existe une variable de niveau 0 et une seconde de
                   1082:                // niveau 1, la variable de niveau 0 (fonction) est masquée
                   1083:                // par celle de niveau 1.
                   1084: 
1.33      bertrand 1085:                if (((*(*(*(*l_variable_courante).feuille).precedent)
                   1086:                        .variable).niveau == 0) && ((*(*(*(*
                   1087:                        (*l_variable_courante).feuille).precedent).precedent)
1.27      bertrand 1088:                        .variable).niveau == 1))
                   1089:                {
                   1090:                    (*s_etat_processus).pointeur_variable_courante =
1.33      bertrand 1091:                            (*(*(*(*l_variable_courante).feuille).precedent)
                   1092:                            .precedent).variable;
                   1093:                    (*s_etat_processus).pointeur_feuille_courante =
1.27      bertrand 1094:                            (*(*(*l_variable_courante).feuille).precedent)
1.33      bertrand 1095:                            .precedent;
1.27      bertrand 1096:                }
                   1097: 
1.30      bertrand 1098:                return(d_vrai);
1.12      bertrand 1099:            }
                   1100:        }
1.1       bertrand 1101:    }
                   1102: 
1.30      bertrand 1103:    (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                   1104:    return(d_faux);
1.1       bertrand 1105: }
                   1106: 
                   1107: 
1.29      bertrand 1108: logical1
                   1109: recherche_variable_globale(struct_processus *s_etat_processus,
                   1110:        unsigned char *nom)
                   1111: {
                   1112:    logical1            presence_variable;
                   1113: 
                   1114:    presence_variable = recherche_variable(s_etat_processus, nom);
                   1115: 
                   1116:    if (presence_variable == d_vrai)
                   1117:    {
                   1118:        switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
                   1119:        {
                   1120:            case 0:
                   1121:            {
1.33      bertrand 1122:                // La variable est une définition.
1.29      bertrand 1123:                presence_variable = d_faux;
                   1124:                break;
                   1125:            }
                   1126: 
                   1127:            case 1:
                   1128:            {
                   1129:                break;
                   1130:            }
                   1131: 
                   1132:            default:
                   1133:            {
                   1134:                if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
                   1135:                        .precedent).variable).niveau == 1)
                   1136:                {
                   1137:                    (*s_etat_processus).pointeur_feuille_courante =
                   1138:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1139:                            .precedent;
                   1140:                    (*s_etat_processus).pointeur_variable_courante =
                   1141:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1142:                            .variable;
                   1143:                }
                   1144:                else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
                   1145:                        .precedent).precedent).variable).niveau == 1)
                   1146:                {
                   1147:                    (*s_etat_processus).pointeur_feuille_courante =
                   1148:                            (*(*(*s_etat_processus).pointeur_feuille_courante)
                   1149:                            .precedent).precedent;
                   1150:                    (*s_etat_processus).pointeur_variable_courante =
                   1151:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1152:                            .variable;
                   1153:                }
                   1154:                else
                   1155:                {
                   1156:                    presence_variable = d_faux;
                   1157:                }
                   1158: 
                   1159:                break;
                   1160:            }
                   1161:        }
                   1162:    }
                   1163: 
                   1164:    if (presence_variable == d_vrai)
                   1165:    {
                   1166:        if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
                   1167:        {
                   1168:            // La variable n'est pas globale, elle est partagée.
                   1169:            presence_variable = d_faux;
                   1170:            (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
                   1171:        }
                   1172:    }
                   1173: 
                   1174:    return(presence_variable);
                   1175: }
                   1176: 
                   1177: 
1.1       bertrand 1178: /*
                   1179: ================================================================================
                   1180:   Procédure de retrait d'une variable de la base
                   1181: ================================================================================
                   1182:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
                   1183:            les globales) ou strictement globale.
                   1184: --------------------------------------------------------------------------------
                   1185:   Sortie :
                   1186: --------------------------------------------------------------------------------
                   1187:   Effets de bord : néant
                   1188: ================================================================================
                   1189: */
                   1190: 
                   1191: logical1
                   1192: retrait_variable(struct_processus *s_etat_processus,
                   1193:        unsigned char *nom_variable, unsigned char type)
                   1194: {
1.28      bertrand 1195:    logical1                    erreur;
1.34      bertrand 1196:    logical1                    variable_supprimee;
1.28      bertrand 1197: 
                   1198:    struct_arbre_variables      *s_arbre_a_supprimer;
                   1199:    struct_arbre_variables      *s_arbre_courant;
                   1200: 
                   1201:    struct_liste_chainee        *l_element_courant;
                   1202:    struct_liste_chainee        *l_element_precedent;
                   1203: 
                   1204:    struct_liste_variables      *variable_a_supprimer;
                   1205:    struct_liste_variables      *variables_par_niveau;
                   1206: 
1.70      bertrand 1207:    integer8                    niveau;
1.1       bertrand 1208: 
1.36      bertrand 1209:    (*s_etat_processus).niveau_supprime = d_faux;
                   1210: 
1.1       bertrand 1211:    if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
                   1212:    {
1.25      bertrand 1213:        // Une variable correspondant au nom recherché est accessible.
                   1214: 
1.1       bertrand 1215:        if (type == 'G')
                   1216:        {
1.25      bertrand 1217:            if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
                   1218:            {
                   1219:                // La variable obtenue est une variable locale. il faut
                   1220:                // s'assurer qu'il existe une variable de niveau 1 de même
                   1221:                // nom sur la feuille.
                   1222: 
1.27      bertrand 1223:                if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
                   1224:                        .precedent).variable).niveau <= 1)
1.1       bertrand 1225:                {
1.27      bertrand 1226:                    (*s_etat_processus).pointeur_feuille_courante =
                   1227:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1228:                            .precedent;
                   1229:                    (*s_etat_processus).pointeur_variable_courante =
                   1230:                            (*(*s_etat_processus).pointeur_feuille_courante)
                   1231:                            .variable;
                   1232: 
                   1233:                    // Si la variable retournée est de niveau 0, on regarde
                   1234:                    // un peu plus loin si une variable de niveau 1 existe.
                   1235: 
                   1236:                    if (((*(*(*s_etat_processus).pointeur_feuille_courante)
                   1237:                            .variable).niveau == 0) &&
                   1238:                            ((*(*(*(*s_etat_processus)
                   1239:                            .pointeur_feuille_courante).precedent).variable)
                   1240:                            .niveau == 1))
1.1       bertrand 1241:                    {
1.27      bertrand 1242:                        (*s_etat_processus).pointeur_feuille_courante =
                   1243:                                (*(*s_etat_processus).pointeur_feuille_courante)
                   1244:                                .precedent;
                   1245:                        (*s_etat_processus).pointeur_variable_courante =
                   1246:                                (*(*s_etat_processus).pointeur_feuille_courante)
                   1247:                                .variable;
1.1       bertrand 1248:                    }
                   1249:                }
1.27      bertrand 1250:                else
                   1251:                {
                   1252:                    // Aucune variable globale (niveau 1) n'existe.
1.1       bertrand 1253: 
1.27      bertrand 1254:                    erreur = d_erreur;
                   1255:                    (*s_etat_processus).erreur_execution =
                   1256:                            d_ex_variable_non_definie;
                   1257:                    return(erreur);
                   1258:                }
1.1       bertrand 1259:            }
                   1260: 
1.27      bertrand 1261:            if ((*(*s_etat_processus).pointeur_variable_courante)
1.1       bertrand 1262:                    .variable_verrouillee == d_vrai)
                   1263:            {
                   1264:                erreur = d_erreur;
                   1265:                (*s_etat_processus).erreur_execution =
                   1266:                        d_ex_variable_verrouillee;
1.28      bertrand 1267:                return(erreur);
1.1       bertrand 1268:            }
                   1269:        }
                   1270: 
1.27      bertrand 1271:        // Suppression de la variable de la liste.
                   1272:        // Deux cas peuvent survenir :
                   1273:        // 1/ les pointeurs sur la variable et la variable suivante
                   1274:        // sont identiques et on supprime la variable ainsi que la feuille
                   1275:        // associée ;
                   1276:        // 2/ ces deux pointeurs sont différents et se contente de retirer
                   1277:        // la structure décrivant la variable.
1.1       bertrand 1278: 
1.28      bertrand 1279:        if ((*s_etat_processus).pointeur_feuille_courante ==
                   1280:                (*(*s_etat_processus).pointeur_feuille_courante).suivant)
                   1281:        {
                   1282:            // Cas 1 :
                   1283:            // On retire la variable du noeud en décrémentant le nombre
                   1284:            // de feuilles de ce noeud. Si le nombre de feuilles du noeud
                   1285:            // est nul, on retire les noeuds récursivement jusqu'à obtenir
                   1286:            // un nombre non nul de feuilles utilisées (ou la racine des
                   1287:            // variables).
                   1288: 
                   1289:            variable_a_supprimer = (*s_etat_processus)
                   1290:                    .pointeur_feuille_courante;
1.34      bertrand 1291:            s_arbre_courant = (*variable_a_supprimer).noeud;
1.28      bertrand 1292:            BUG((*s_arbre_courant).noeuds_utilises == 0,
                   1293:                    uprintf("Freed node !\n"));
                   1294:            (*s_arbre_courant).noeuds_utilises--;
1.1       bertrand 1295: 
1.34      bertrand 1296:            (*((*(*variable_a_supprimer).noeud_pere).noeuds
                   1297:                    [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                   1298:                    .feuille = NULL;
                   1299: 
1.58      bertrand 1300:            while(((*s_arbre_courant).noeuds_utilises == 0) &&
1.65      bertrand 1301:                    ((*s_arbre_courant).feuille_statique == NULL))
1.28      bertrand 1302:            {
                   1303:                s_arbre_a_supprimer = s_arbre_courant;
                   1304:                s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1       bertrand 1305: 
1.28      bertrand 1306:                if (s_arbre_courant == NULL)
                   1307:                {
1.40      bertrand 1308:                    liberation_tableau_noeuds(s_etat_processus,
                   1309:                            (*s_arbre_a_supprimer).noeuds);
                   1310:                    liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.34      bertrand 1311: 
                   1312:                    (*s_etat_processus).s_arbre_variables = NULL;
1.28      bertrand 1313:                    break;
                   1314:                }
                   1315: 
1.31      bertrand 1316:                // s_arbre_a_supprimer contient la structure de feuille qui
                   1317:                // vient d'être libérée. Il s'agit maintenant
                   1318:                // d'annuler le pointeur dans le tableau noeuds de la structure
                   1319:                // pointée par noeud_pere, soit s_arbre_courant.
                   1320: 
                   1321:                BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
                   1322:                        uprintf("Invalid pointer !\n"));
                   1323:                (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
                   1324:                        .indice_tableau_pere] = NULL;
                   1325: 
1.40      bertrand 1326:                liberation_tableau_noeuds(s_etat_processus,
                   1327:                        (*s_arbre_a_supprimer).noeuds);
                   1328:                liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.31      bertrand 1329: 
1.28      bertrand 1330:                BUG((*s_arbre_courant).noeuds_utilises == 0,
                   1331:                        uprintf("Freed node !\n"));
                   1332:                (*s_arbre_courant).noeuds_utilises--;
                   1333:            }
                   1334:        }
                   1335:        else
1.1       bertrand 1336:        {
1.28      bertrand 1337:            // Cas 2 :
                   1338:            // On retire la variable de la liste.
                   1339: 
                   1340:            variable_a_supprimer = (*s_etat_processus)
                   1341:                    .pointeur_feuille_courante;
                   1342: 
                   1343:            (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
                   1344:                    .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
                   1345:                    .suivant;
                   1346:            (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
                   1347:                    .precedent = (*(*s_etat_processus)
                   1348:                    .pointeur_feuille_courante).precedent;
1.32      bertrand 1349: 
1.33      bertrand 1350:            // Mise à jour du pointeur dans l'arbre des variables. Cette
                   1351:            // mise à jour n'est nécessaire que dans le cas où la variable
                   1352:            // supprimée est en tête de la liste.
                   1353: 
                   1354:            if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
                   1355:                    .noeuds[(*(*variable_a_supprimer).noeud)
                   1356:                    .indice_tableau_pere])).feuille)
                   1357:            {
                   1358:                (*((*(*variable_a_supprimer).noeud_pere).noeuds
                   1359:                        [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
                   1360:                        .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
                   1361:                        .noeuds[(*(*variable_a_supprimer).noeud)
                   1362:                        .indice_tableau_pere])).feuille).suivant;
                   1363:            }
                   1364: 
                   1365:            (*s_etat_processus).pointeur_feuille_courante =
                   1366:                    (*(*s_etat_processus).pointeur_feuille_courante).suivant;
                   1367:            (*s_etat_processus).pointeur_variable_courante =
                   1368:                    (*(*s_etat_processus).pointeur_feuille_courante).variable;
1.1       bertrand 1369:        }
                   1370: 
1.28      bertrand 1371:        // Dans tous les cas, on retire la variable de la liste des variables
                   1372:        // par niveau.
                   1373: 
                   1374:        niveau = (*(*variable_a_supprimer).variable).niveau;
                   1375:        variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1.34      bertrand 1376:        variable_supprimee = d_faux;
1.28      bertrand 1377: 
1.31      bertrand 1378:        if (variables_par_niveau != NULL)
1.28      bertrand 1379:        {
1.31      bertrand 1380:            do
                   1381:            {
                   1382:                l_element_courant = (*variables_par_niveau).liste;
1.28      bertrand 1383: 
1.31      bertrand 1384:                if (l_element_courant != NULL)
1.28      bertrand 1385:                {
1.31      bertrand 1386:                    if ((*((struct_variable *) (*l_element_courant).donnee))
                   1387:                            .niveau == niveau)
                   1388:                    {
                   1389:                        // On parcourt le bon niveau.
1.28      bertrand 1390: 
1.31      bertrand 1391:                        l_element_precedent = NULL;
1.28      bertrand 1392: 
1.31      bertrand 1393:                        while(l_element_courant != NULL)
1.28      bertrand 1394:                        {
1.31      bertrand 1395:                            // Tant que l_element_courant est non nul, il reste
                   1396:                            // des variables à explorer dans le niveau courant.
1.28      bertrand 1397: 
1.31      bertrand 1398:                            if ((*l_element_courant).donnee ==
                   1399:                                    (void *) (*variable_a_supprimer).variable)
1.28      bertrand 1400:                            {
1.31      bertrand 1401:                                // On a trouvé la variable à supprimer.
                   1402: 
                   1403:                                if (l_element_precedent == NULL)
                   1404:                                {
                   1405:                                    (*variables_par_niveau).liste =
                   1406:                                            (*l_element_courant).suivant;
                   1407:                                }
                   1408:                                else
                   1409:                                {
                   1410:                                    (*l_element_precedent).suivant =
                   1411:                                            (*l_element_courant).suivant;
                   1412:                                }
                   1413: 
1.40      bertrand 1414:                                liberation_maillon(s_etat_processus,
                   1415:                                        l_element_courant);
1.34      bertrand 1416: 
                   1417:                                if ((*variables_par_niveau).liste == NULL)
                   1418:                                {
1.36      bertrand 1419:                                    (*s_etat_processus).niveau_supprime =
                   1420:                                            d_vrai;
                   1421: 
1.34      bertrand 1422:                                    if ((*s_etat_processus)
                   1423:                                            .l_liste_variables_par_niveau
                   1424:                                            == variables_par_niveau)
                   1425:                                    {
                   1426:                                        // On retire l'élément de la liste
                   1427:                                        // pointé par
                   1428:                                        // l_liste_variable_par_niveau
                   1429: 
                   1430:                                        (*s_etat_processus)
                   1431:                                                .l_liste_variables_par_niveau =
                   1432:                                                (*variables_par_niveau).suivant;
                   1433:                                    }
                   1434: 
                   1435:                                    (*(*variables_par_niveau).precedent)
                   1436:                                            .suivant =
                   1437:                                            (*variables_par_niveau).suivant;
                   1438:                                    (*(*variables_par_niveau).suivant)
                   1439:                                            .precedent =
                   1440:                                            (*variables_par_niveau)
                   1441:                                            .precedent;
1.40      bertrand 1442:                                    liberation_feuille(s_etat_processus,
                   1443:                                            variables_par_niveau);
1.34      bertrand 1444:                                }
                   1445: 
                   1446:                                variable_supprimee = d_vrai;
1.31      bertrand 1447:                                break;
1.28      bertrand 1448:                            }
1.31      bertrand 1449: 
                   1450:                            l_element_precedent = l_element_courant;
                   1451:                            l_element_courant = (*l_element_courant).suivant;
1.28      bertrand 1452:                        }
                   1453:                    }
                   1454:                }
                   1455: 
1.34      bertrand 1456:                if (variable_supprimee == d_vrai)
                   1457:                {
                   1458:                    break;
                   1459:                }
                   1460: 
1.31      bertrand 1461:                variables_par_niveau = (*variables_par_niveau).suivant;
                   1462: 
                   1463:            } while(variables_par_niveau != (*s_etat_processus)
                   1464:                    .l_liste_variables_par_niveau);
1.28      bertrand 1465:        }
                   1466: 
                   1467:        // Puis on libère le contenu de la variable.
                   1468: 
                   1469:        free((*(*variable_a_supprimer).variable).nom);
                   1470:        liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.40      bertrand 1471:        liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
                   1472:        liberation_feuille(s_etat_processus, variable_a_supprimer);
1.28      bertrand 1473: 
1.1       bertrand 1474:        erreur = d_absence_erreur;
                   1475:    }
                   1476:    else
                   1477:    {
1.25      bertrand 1478:        // Aucune variable n'est accessible depuis le point courant du
                   1479:        // programme.
                   1480: 
1.1       bertrand 1481:        erreur = d_erreur;
                   1482:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                   1483:    }
                   1484: 
1.25      bertrand 1485:    return(erreur);
1.1       bertrand 1486: }
                   1487: 
                   1488: 
                   1489: /*
                   1490: ================================================================================
                   1491:   Procédure de retrait des variables de niveau strictement supérieur au
                   1492:   niveau courant
                   1493: ================================================================================
                   1494:   Entrée :
                   1495: --------------------------------------------------------------------------------
                   1496:   Sortie :
                   1497: --------------------------------------------------------------------------------
                   1498:   Effets de bord : néant
                   1499: ================================================================================
                   1500: */
                   1501: 
                   1502: logical1
1.59      bertrand 1503: retrait_variables_par_niveau(struct_processus *s_etat_processus)
1.1       bertrand 1504: {
1.31      bertrand 1505:    struct_liste_variables          *l_element_a_supprimer;
                   1506: 
1.28      bertrand 1507:    // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
                   1508:    // La tête de la pile contient toujours les variables de plus haut niveau
                   1509:    // créées.
1.1       bertrand 1510: 
1.28      bertrand 1511:    while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1       bertrand 1512:    {
1.28      bertrand 1513:        if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1       bertrand 1514:        {
1.28      bertrand 1515:            // Si le niveau ne contient aucune variable, on le détruit.
                   1516:            // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
                   1517:            // faire.
1.1       bertrand 1518:        }
                   1519:        else
                   1520:        {
1.28      bertrand 1521:            // Le niveau contient des variables.
                   1522: 
                   1523:            if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1524:                    .l_liste_variables_par_niveau).liste).donnee)).niveau
                   1525:                    <= (*s_etat_processus).niveau_courant)
1.1       bertrand 1526:            {
1.28      bertrand 1527:                // On a retiré de l'arbre des variables toutes les
                   1528:                // variables de niveau strictement supérieur au niveau
                   1529:                // courant.
1.1       bertrand 1530: 
1.28      bertrand 1531:                break;
1.1       bertrand 1532:            }
1.28      bertrand 1533: 
1.74      bertrand 1534:            if (((*s_etat_processus).at_exit != NULL) &&
                   1535:                    ((*s_etat_processus).niveau_courant == 0))
                   1536:            {
                   1537:                // Il y a une routine ATEXIT enregistrée. On ne détruit pas
                   1538:                // les variables globales qui pourraient y être utilisées.
                   1539: 
                   1540:                break;
                   1541:            }
                   1542: 
1.28      bertrand 1543:            while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
                   1544:                    != NULL)
1.1       bertrand 1545:            {
1.34      bertrand 1546:                // Nécessaire car le pointeur sur la tête de la pile
                   1547:                // peut être modifié par retrait_variable().
1.28      bertrand 1548:                // Sauvegarde des variables statiques.
                   1549: 
                   1550:                if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1551:                        .l_liste_variables_par_niveau).liste).donnee)).origine
                   1552:                        == 'P')
1.1       bertrand 1553:                {
1.28      bertrand 1554:                    if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1555:                            .l_liste_variables_par_niveau).liste).donnee))
                   1556:                            .variable_statique.adresse != 0)
1.1       bertrand 1557:                    {
1.28      bertrand 1558:                        if (recherche_variable_statique(s_etat_processus,
                   1559:                                (*((struct_variable *) (*(*(*s_etat_processus)
                   1560:                                .l_liste_variables_par_niveau).liste).donnee))
                   1561:                                .nom, (*((struct_variable *)
                   1562:                                (*(*(*s_etat_processus)
                   1563:                                .l_liste_variables_par_niveau).liste).donnee))
                   1564:                                .variable_statique, ((*s_etat_processus)
                   1565:                                .mode_execution_programme
1.59      bertrand 1566:                                 == 'Y') ? 'P' : 'E') != NULL)
1.28      bertrand 1567:                        {
1.59      bertrand 1568:                            (*(*s_etat_processus)
                   1569:                                    .pointeur_variable_statique_courante)
                   1570:                                    .objet = (*((struct_variable *)
1.28      bertrand 1571:                                    (*(*(*s_etat_processus)
                   1572:                                    .l_liste_variables_par_niveau).liste)
                   1573:                                    .donnee)).objet;
                   1574:                        }
                   1575:                        else
                   1576:                        {
                   1577:                            (*s_etat_processus).erreur_systeme =
                   1578:                                    d_es_variable_introuvable;
                   1579:                        }
                   1580: 
                   1581:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1582:                                .l_liste_variables_par_niveau).liste).donnee))
                   1583:                                .objet = NULL;
1.1       bertrand 1584:                    }
1.28      bertrand 1585:                }
                   1586:                else
                   1587:                {
                   1588:                    if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1589:                            .l_liste_variables_par_niveau).liste).donnee))
                   1590:                            .variable_statique.pointeur != NULL)
1.1       bertrand 1591:                    {
1.28      bertrand 1592:                        /*
                   1593:                         * Gestion des variables statiques
                   1594:                         */
                   1595: 
                   1596:                        if (recherche_variable_statique(s_etat_processus,
                   1597:                                (*((struct_variable *) (*(*(*s_etat_processus)
                   1598:                                .l_liste_variables_par_niveau).liste).donnee))
                   1599:                                .nom, (*((struct_variable *)
                   1600:                                (*(*(*s_etat_processus)
                   1601:                                .l_liste_variables_par_niveau).liste).donnee))
                   1602:                                .variable_statique, ((*s_etat_processus)
                   1603:                                .mode_execution_programme
1.59      bertrand 1604:                                 == 'Y') ? 'P' : 'E') != NULL)
1.28      bertrand 1605:                        {
1.59      bertrand 1606:                            (*(*s_etat_processus)
                   1607:                                    .pointeur_variable_statique_courante)
1.28      bertrand 1608:                                    .objet = (*((struct_variable *)
                   1609:                                    (*(*(*s_etat_processus)
                   1610:                                    .l_liste_variables_par_niveau).liste)
                   1611:                                    .donnee)).objet;
                   1612:                        }
                   1613:                        else
                   1614:                        {
                   1615:                            (*s_etat_processus).erreur_systeme =
                   1616:                                    d_es_variable_introuvable;
                   1617:                            return(d_erreur);
                   1618:                        }
                   1619: 
                   1620:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1621:                                .l_liste_variables_par_niveau).liste).donnee))
                   1622:                                .objet = NULL;
1.1       bertrand 1623:                    }
1.28      bertrand 1624:                }
1.1       bertrand 1625: 
1.28      bertrand 1626:                if (retrait_variable(s_etat_processus,
                   1627:                        (*((struct_variable *) (*(*(*s_etat_processus)
                   1628:                        .l_liste_variables_par_niveau).liste).donnee)).nom,
                   1629:                        'L') == d_erreur)
                   1630:                {
                   1631:                    return(d_erreur);
1.1       bertrand 1632:                }
1.34      bertrand 1633: 
                   1634:                if ((*((struct_variable *) (*(*(*s_etat_processus)
                   1635:                        .l_liste_variables_par_niveau).liste).donnee)).niveau
                   1636:                        <= (*s_etat_processus).niveau_courant)
                   1637:                {
                   1638:                    // On a retiré de l'arbre des variables toutes les
                   1639:                    // variables de niveau strictement supérieur au niveau
                   1640:                    // courant.
                   1641: 
                   1642:                    return(d_absence_erreur);
                   1643:                }
1.1       bertrand 1644:            }
                   1645:        }
                   1646: 
1.31      bertrand 1647:        // On retire l'élément de la liste doublement chaînée et circulaire.
                   1648: 
                   1649:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
                   1650:                = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
                   1651:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
                   1652:                = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
                   1653: 
                   1654:        l_element_a_supprimer = (*s_etat_processus)
                   1655:                .l_liste_variables_par_niveau;
                   1656:        (*s_etat_processus).l_liste_variables_par_niveau =
                   1657:                (*l_element_a_supprimer).suivant;
1.40      bertrand 1658:        liberation_feuille(s_etat_processus, l_element_a_supprimer);
1.1       bertrand 1659:    }
                   1660: 
                   1661:    return(d_absence_erreur);
                   1662: }
                   1663: 
1.23      bertrand 1664: 
                   1665: /*
                   1666: ================================================================================
1.24      bertrand 1667:   Procédure de retrait des toutes les variables locales et globales
                   1668: ================================================================================
                   1669:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
                   1670:            de niveau 0)
                   1671: --------------------------------------------------------------------------------
                   1672:   Sortie :
                   1673: --------------------------------------------------------------------------------
                   1674:   Effets de bord : néant
                   1675: ================================================================================
                   1676: */
                   1677: 
                   1678: void
                   1679: liberation_arbre_variables(struct_processus *s_etat_processus,
                   1680:        struct_arbre_variables *arbre, logical1 retrait_definitions)
                   1681: {
1.58      bertrand 1682:    int                                 i;
                   1683: 
                   1684:    struct_liste_chainee                *l_element_courant_liste;
                   1685:    struct_liste_chainee                *l_element_suivant_liste;
1.24      bertrand 1686: 
1.58      bertrand 1687:    struct_liste_variables              *l_element_courant;
                   1688:    struct_liste_variables              *l_element_suivant;
1.28      bertrand 1689: 
1.58      bertrand 1690:    struct_liste_variables_statiques    *l_element_statique_courant;
                   1691:    struct_liste_variables_statiques    *l_element_statique_suivant;
1.28      bertrand 1692: 
                   1693:    // Libération de l'arbre des variables. Le contenu des variables n'est
                   1694:    // pas détruit par cette opération, il sera détruit lors de la libération
                   1695:    // de la liste des variables par niveau.
1.24      bertrand 1696: 
1.34      bertrand 1697:    if (arbre == NULL)
                   1698:    {
                   1699:        return;
                   1700:    }
                   1701: 
1.31      bertrand 1702:    l_element_courant = (*arbre).feuille;
                   1703: 
                   1704:    if (l_element_courant != NULL)
                   1705:    {
                   1706:        do
                   1707:        {
                   1708:            l_element_suivant = (*l_element_courant).suivant;
1.40      bertrand 1709:            liberation_feuille(s_etat_processus, l_element_courant);
1.31      bertrand 1710:            l_element_courant = l_element_suivant;
                   1711:        } while(l_element_courant != (*arbre).feuille);
1.38      bertrand 1712: 
                   1713:        (*arbre).feuille = NULL;
1.31      bertrand 1714:    }
                   1715: 
1.58      bertrand 1716:    l_element_statique_courant = (*arbre).feuille_statique;
                   1717: 
                   1718:    while(l_element_statique_courant != NULL)
                   1719:    {
                   1720:        l_element_statique_suivant = (*l_element_statique_courant).suivant;
                   1721: 
                   1722:        free((*(*l_element_statique_courant).variable).nom);
                   1723:        liberation(s_etat_processus, (*(*l_element_statique_courant)
                   1724:                .variable).objet);
1.61      bertrand 1725:        free((*l_element_statique_courant).variable);
                   1726:        free(l_element_statique_courant);
1.58      bertrand 1727: 
                   1728:        l_element_statique_courant = l_element_statique_suivant;
                   1729:    }
                   1730: 
1.24      bertrand 1731:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1732:    {
1.28      bertrand 1733:        if ((*arbre).noeuds[i] != NULL)
1.24      bertrand 1734:        {
1.28      bertrand 1735:            liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
                   1736:                    retrait_definitions);
1.38      bertrand 1737:            (*arbre).noeuds[i] = NULL;
1.28      bertrand 1738:        }
                   1739:    }
                   1740: 
                   1741:    // Suppression de la liste des variables par niveau.
                   1742: 
                   1743:    if (arbre == (*s_etat_processus).s_arbre_variables)
                   1744:    {
                   1745:        l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
                   1746: 
1.31      bertrand 1747:        if (l_element_courant != NULL)
1.28      bertrand 1748:        {
1.31      bertrand 1749:            do
                   1750:            {
                   1751:                l_element_courant_liste = (*l_element_courant).liste;
1.24      bertrand 1752: 
1.31      bertrand 1753:                while(l_element_courant_liste != NULL)
1.24      bertrand 1754:                {
1.31      bertrand 1755:                    if ((retrait_definitions == d_vrai) ||
                   1756:                            ((*((struct_variable *) (*l_element_courant_liste)
                   1757:                            .donnee)).niveau >= 1))
                   1758:                    {
                   1759:                        liberation(s_etat_processus, (*((struct_variable *)
                   1760:                                (*l_element_courant_liste).donnee)).objet);
                   1761:                        free((*((struct_variable *) (*l_element_courant_liste)
                   1762:                                .donnee)).nom);
                   1763:                    }
                   1764: 
                   1765:                    l_element_suivant_liste =
                   1766:                            (*l_element_courant_liste).suivant;
1.40      bertrand 1767:                    liberation_variable(s_etat_processus, (struct_variable *)
                   1768:                            (*l_element_courant_liste).donnee);
                   1769:                    liberation_maillon(s_etat_processus,
                   1770:                            l_element_courant_liste);
1.31      bertrand 1771:                    l_element_courant_liste = l_element_suivant_liste;
1.24      bertrand 1772:                }
                   1773: 
1.31      bertrand 1774:                l_element_suivant = (*l_element_courant).suivant;
1.40      bertrand 1775:                liberation_feuille(s_etat_processus, l_element_courant);
1.31      bertrand 1776:                l_element_courant = l_element_suivant;
                   1777:            } while(l_element_courant != (*s_etat_processus)
                   1778:                    .l_liste_variables_par_niveau);
1.24      bertrand 1779:        }
                   1780:    }
                   1781: 
1.40      bertrand 1782:    liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
                   1783:    liberation_noeud(s_etat_processus, arbre);
1.38      bertrand 1784:    arbre = NULL;
1.24      bertrand 1785: 
                   1786:    return;
                   1787: }
                   1788: 
1.28      bertrand 1789: 
1.24      bertrand 1790: /*
                   1791: ================================================================================
1.33      bertrand 1792:   Procédure renvoyant les variables dans un tableau
                   1793: ================================================================================
                   1794:   Entrée :
                   1795: --------------------------------------------------------------------------------
                   1796:   Sortie :
                   1797: --------------------------------------------------------------------------------
                   1798:   Effets de bord : néant
                   1799: ================================================================================
                   1800: */
                   1801: 
1.70      bertrand 1802: static integer8
1.65      bertrand 1803: nombre_variables_locales(struct_processus *s_etat_processus,
1.33      bertrand 1804:        struct_arbre_variables *l_element_courant)
                   1805: {
1.70      bertrand 1806:    integer8                            i;
                   1807:    integer8                            n;
1.33      bertrand 1808: 
1.60      bertrand 1809:    struct_liste_variables              *l_variable;
                   1810:    struct_liste_variables_statiques    *l_variable_statique;
1.33      bertrand 1811: 
1.65      bertrand 1812:    if (l_element_courant == NULL)
                   1813:    {
                   1814:        return(0);
                   1815:    }
                   1816: 
1.33      bertrand 1817:    n = 0;
                   1818: 
                   1819:    if ((*l_element_courant).feuille != NULL)
                   1820:    {
                   1821:        l_variable = (*l_element_courant).feuille;
                   1822: 
                   1823:        do
                   1824:        {
                   1825:            n++;
                   1826:            l_variable = (*l_variable).suivant;
                   1827:        } while(l_variable != (*l_element_courant).feuille);
                   1828:    }
                   1829: 
1.60      bertrand 1830:    if ((*l_element_courant).feuille_statique != NULL)
                   1831:    {
                   1832:        l_variable_statique = (*l_element_courant).feuille_statique;
                   1833: 
                   1834:        do
                   1835:        {
                   1836:            // Si le pointeur est nul, la variable est accessible et a été
                   1837:            // copiée dans l'arbre des variables.
                   1838: 
                   1839:            if ((*(*l_variable_statique).variable).objet != NULL)
                   1840:            {
                   1841:                n++;
                   1842:            }
                   1843: 
                   1844:            l_variable_statique = (*l_variable_statique).suivant;
                   1845:        } while(l_variable_statique != NULL);
                   1846:    }
                   1847: 
1.33      bertrand 1848:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1849:    {
                   1850:        if ((*l_element_courant).noeuds[i] != NULL)
                   1851:        {
1.65      bertrand 1852:            n += nombre_variables_locales(s_etat_processus,
                   1853:                    (*l_element_courant).noeuds[i]);
                   1854:        }
                   1855:    }
                   1856: 
                   1857:    return(n);
                   1858: }
                   1859: 
                   1860: 
1.70      bertrand 1861: static integer8
1.65      bertrand 1862: nombre_variables_partagees(struct_processus *s_etat_processus,
                   1863:        struct_arbre_variables_partagees *l_element_courant)
                   1864: {
1.70      bertrand 1865:    integer8                            i;
                   1866:    integer8                            n;
1.65      bertrand 1867: 
                   1868:    struct_liste_variables_partagees    *l_variable;
                   1869: 
                   1870:    if (l_element_courant == NULL)
                   1871:    {
                   1872:        return(0);
                   1873:    }
                   1874: 
1.73      bertrand 1875:    // Mutex deverrouillé par liste_variables_partagees();
1.65      bertrand 1876:    if (pthread_mutex_lock(&((*l_element_courant).mutex_feuille)) != 0)
                   1877:    {
                   1878:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1879:        return(0);
                   1880:    }
                   1881: 
                   1882:    n = 0;
                   1883: 
                   1884:    if ((*l_element_courant).feuille != NULL)
                   1885:    {
                   1886:        l_variable = (*l_element_courant).feuille;
                   1887: 
                   1888:        do
                   1889:        {
                   1890:            n++;
                   1891:            l_variable = (*l_variable).suivant;
                   1892:        } while(l_variable != NULL);
                   1893:    }
                   1894: 
                   1895:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1896:    {
                   1897:        if ((*l_element_courant).noeuds[i] != NULL)
                   1898:        {
                   1899:            n += nombre_variables_partagees(s_etat_processus,
1.33      bertrand 1900:                    (*l_element_courant).noeuds[i]);
                   1901:        }
                   1902:    }
                   1903: 
                   1904:    return(n);
                   1905: }
                   1906: 
1.53      bertrand 1907: 
1.70      bertrand 1908: integer8
1.65      bertrand 1909: nombre_variables(struct_processus *s_etat_processus)
                   1910: {
                   1911:    return(nombre_variables_locales(s_etat_processus,
                   1912:            (*s_etat_processus).s_arbre_variables)
                   1913:            + nombre_variables_partagees(s_etat_processus,
                   1914:            (*(*s_etat_processus).s_arbre_variables_partagees)));
                   1915: }
                   1916: 
                   1917: 
                   1918: void
                   1919: liberation_mutexes_arbre_variables_partagees(struct_processus *s_etat_processus,
                   1920:        struct_arbre_variables_partagees *l_element_courant)
                   1921: {
                   1922:    int                                 i;
                   1923: 
                   1924:    if (l_element_courant == NULL)
                   1925:    {
                   1926:        return;
                   1927:    }
                   1928: 
                   1929:    if (pthread_mutex_trylock(&((*l_element_courant).mutex_feuille)) != 0)
                   1930:    {
                   1931:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1932:        return;
                   1933:    }
                   1934: 
                   1935:    if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
                   1936:    {
                   1937:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1938:        return;
                   1939:    }
                   1940: 
                   1941:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   1942:    {
                   1943:        if ((*l_element_courant).noeuds[i] != NULL)
                   1944:        {
                   1945:            liberation_mutexes_arbre_variables_partagees(s_etat_processus,
                   1946:                    (*l_element_courant).noeuds[i]);
                   1947:        }
                   1948:    }
                   1949: 
                   1950:    return;
                   1951: }
                   1952: 
                   1953: 
1.70      bertrand 1954: static integer8
1.65      bertrand 1955: liste_variables_locales(struct_processus *s_etat_processus,
1.70      bertrand 1956:        struct_tableau_variables *tableau, integer8 position,
1.33      bertrand 1957:        struct_arbre_variables *l_element_courant)
                   1958: {
1.70      bertrand 1959:    integer8                            i;
1.33      bertrand 1960: 
1.60      bertrand 1961:    struct_liste_variables              *l_variable;
                   1962:    struct_liste_variables_statiques    *l_variable_statique;
1.33      bertrand 1963: 
1.65      bertrand 1964:    if (l_element_courant == NULL)
                   1965:    {
1.72      bertrand 1966:        return(position);
1.65      bertrand 1967:    }
                   1968: 
1.33      bertrand 1969:    if ((*l_element_courant).feuille != NULL)
                   1970:    {
                   1971:        l_variable = (*l_element_courant).feuille;
                   1972: 
                   1973:        do
                   1974:        {
                   1975:            tableau[position].origine = (*(*l_variable).variable).origine;
                   1976:            tableau[position].nom = (*(*l_variable).variable).nom;
                   1977:            tableau[position].niveau = (*(*l_variable).variable).niveau;
                   1978:            tableau[position].objet = (*(*l_variable).variable).objet;
                   1979:            tableau[position].variable_verrouillee =
                   1980:                    (*(*l_variable).variable).variable_verrouillee;
                   1981:            tableau[position].variable_statique =
                   1982:                    (*(*l_variable).variable).variable_statique;
                   1983:            tableau[position].variable_partagee =
                   1984:                    (*(*l_variable).variable).variable_partagee;
1.60      bertrand 1985:            tableau[position].variable_masquee = d_faux;
1.72      bertrand 1986:            tableau[position].mutex = NULL;
1.33      bertrand 1987: 
                   1988:            position++;
1.72      bertrand 1989: 
1.33      bertrand 1990:            l_variable = (*l_variable).suivant;
                   1991:        } while(l_variable != (*l_element_courant).feuille);
                   1992:    }
                   1993: 
1.60      bertrand 1994:    if ((*l_element_courant).feuille_statique != NULL)
                   1995:    {
                   1996:        l_variable_statique = (*l_element_courant).feuille_statique;
                   1997: 
                   1998:        do
                   1999:        {
                   2000:            if ((*(*l_variable_statique).variable).objet != NULL)
                   2001:            {
                   2002:                tableau[position].origine = 'E';
                   2003:                tableau[position].nom = (*(*l_variable_statique).variable).nom;
                   2004:                tableau[position].niveau =
                   2005:                        (*(*l_variable_statique).variable).niveau;
1.72      bertrand 2006:                tableau[position].objet = (*(*l_variable_statique).variable)
                   2007:                        .objet;
1.60      bertrand 2008:                tableau[position].variable_verrouillee = d_faux;
                   2009:                tableau[position].variable_statique =
                   2010:                        (*(*l_variable_statique).variable).variable_statique;
                   2011:                tableau[position].variable_partagee.pointeur = NULL;
                   2012:                tableau[position].variable_masquee = d_vrai;
1.88      bertrand 2013:                tableau[position].mutex = NULL;
1.60      bertrand 2014: 
                   2015:                position++;
                   2016:            }
                   2017: 
                   2018:            l_variable_statique = (*l_variable_statique).suivant;
                   2019:        } while(l_variable_statique != NULL);
                   2020:    }
                   2021: 
1.33      bertrand 2022:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   2023:    {
                   2024:        if ((*l_element_courant).noeuds[i] != NULL)
                   2025:        {
1.65      bertrand 2026:            position = liste_variables_locales(s_etat_processus,
                   2027:                    tableau, position, (*l_element_courant).noeuds[i]);
                   2028:        }
                   2029:    }
                   2030: 
                   2031:    return(position);
                   2032: }
                   2033: 
                   2034: 
1.70      bertrand 2035: static integer8
1.65      bertrand 2036: liste_variables_partagees(struct_processus *s_etat_processus,
1.70      bertrand 2037:        struct_tableau_variables *tableau, integer8 position,
1.65      bertrand 2038:        struct_arbre_variables_partagees *l_element_courant)
                   2039: {
1.70      bertrand 2040:    integer8                            i;
1.65      bertrand 2041: 
                   2042:    struct_liste_variables_partagees    *l_variable;
                   2043: 
                   2044:    if (l_element_courant == NULL)
                   2045:    {
1.72      bertrand 2046:        return(position);
1.65      bertrand 2047:    }
                   2048: 
                   2049:    if ((*l_element_courant).feuille != NULL)
                   2050:    {
                   2051:        l_variable = (*l_element_courant).feuille;
                   2052: 
                   2053:        do
                   2054:        {
                   2055:            tableau[position].origine = 'E';
                   2056:            tableau[position].nom = (*(*l_variable).variable).nom;
                   2057:            tableau[position].niveau = (*(*l_variable).variable).niveau;
                   2058:            tableau[position].objet = (*(*l_variable).variable).objet;
                   2059:            tableau[position].variable_verrouillee = d_faux;
                   2060:            tableau[position].variable_partagee =
                   2061:                    (*(*l_variable).variable).variable_partagee;
1.73      bertrand 2062:            tableau[position].variable_statique.pointeur = NULL;
1.65      bertrand 2063:            tableau[position].variable_masquee = d_faux;
1.72      bertrand 2064:            tableau[position].mutex = &((*(*l_variable).variable).mutex);
1.73      bertrand 2065:            pthread_mutex_lock(tableau[position].mutex);
1.65      bertrand 2066: 
                   2067:            position++;
                   2068: 
                   2069:            l_variable = (*l_variable).suivant;
                   2070:        } while(l_variable != NULL);
                   2071:    }
                   2072: 
                   2073:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                   2074:    {
                   2075:        if ((*l_element_courant).noeuds[i] != NULL)
                   2076:        {
                   2077:            position = liste_variables_partagees(s_etat_processus,
1.33      bertrand 2078:                    tableau, position, (*l_element_courant).noeuds[i]);
                   2079:        }
                   2080:    }
                   2081: 
1.73      bertrand 2082:    // Mutex verrouillé par nombre_variables_partagees();
1.72      bertrand 2083:    if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
                   2084:    {
                   2085:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   2086:        return(0);
                   2087:    }
                   2088: 
1.33      bertrand 2089:    return(position);
                   2090: }
                   2091: 
1.47      bertrand 2092: 
1.65      bertrand 2093: static int
                   2094: fonction_ordre_variables(const void *argument_1, const void *argument_2)
                   2095: {
                   2096:    int                         comparaison;
                   2097: 
                   2098:    struct_tableau_variables    *a1;
                   2099:    struct_tableau_variables    *a2;
                   2100: 
                   2101:    a1 = (struct_tableau_variables *) argument_1;
                   2102:    a2 = (struct_tableau_variables *) argument_2;
                   2103: 
                   2104:    comparaison = strcmp((*a1).nom, (*a2).nom);
                   2105: 
                   2106:    if (comparaison != 0)
                   2107:    {
                   2108:        return(comparaison);
                   2109:    }
                   2110:    else
                   2111:    {
1.70      bertrand 2112:        return(((((*a1).niveau - (*a2).niveau)) > 0) ? 1 : -1);
1.65      bertrand 2113:    }
                   2114: }
                   2115: 
                   2116: 
1.70      bertrand 2117: integer8
1.65      bertrand 2118: liste_variables(struct_processus *s_etat_processus,
                   2119:        struct_tableau_variables *tableau)
                   2120: {
1.70      bertrand 2121:    integer8        nombre_elements;
1.65      bertrand 2122: 
                   2123:    nombre_elements = liste_variables_locales(s_etat_processus,
                   2124:            tableau, 0, (*s_etat_processus).s_arbre_variables);
1.72      bertrand 2125:    nombre_elements = liste_variables_partagees(s_etat_processus,
1.65      bertrand 2126:            tableau, nombre_elements, (*(*s_etat_processus)
                   2127:            .s_arbre_variables_partagees));
                   2128: 
1.70      bertrand 2129:    qsort(tableau, (size_t) nombre_elements, sizeof(struct_tableau_variables),
1.65      bertrand 2130:            fonction_ordre_variables);
                   2131: 
                   2132:    return(nombre_elements);
                   2133: }
                   2134: 
                   2135: 
1.33      bertrand 2136: /*
                   2137: ================================================================================
1.23      bertrand 2138:   Procédure de copie de l'arbre des variables
                   2139: ================================================================================
                   2140:   Entrée :
                   2141: --------------------------------------------------------------------------------
                   2142:   Sortie :
                   2143: --------------------------------------------------------------------------------
                   2144:   Effets de bord : néant
                   2145: ================================================================================
                   2146: */
                   2147: 
1.38      bertrand 2148: void
                   2149: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
                   2150:        *s_nouvel_etat_processus)
1.23      bertrand 2151: {
                   2152:    // Les définitions sont partagées entre tous les threads et ne sont pas
                   2153:    // copiées.
1.28      bertrand 2154:    //
                   2155:    // NB : on ne copie que les variables de niveaux 0 et 1, les autres
                   2156:    // variables locales étant masquées par le processus de création de thread
1.38      bertrand 2157:    // ou de processus, elles seront inaccessibles de tous les points
                   2158:    // du fil d'exécution fils.
                   2159: 
                   2160:    // Pour copier ces variables, on récupère les variables depuis la liste par
                   2161:    // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
                   2162:    // structure. Les variables de niveau 0 étant non modifiables, elles
                   2163:    // ne sont pas dupliquées.
                   2164: 
1.60      bertrand 2165:    int                                 i;
1.38      bertrand 2166: 
1.60      bertrand 2167:    logical1                            niveau_0_traite;
                   2168:    logical1                            niveau_1_traite;
1.47      bertrand 2169: 
1.60      bertrand 2170:    struct_arbre_variables              *l_variable_courante;
1.38      bertrand 2171: 
1.60      bertrand 2172:    struct_liste_chainee                *l_element_courant;
1.38      bertrand 2173: 
1.60      bertrand 2174:    struct_liste_variables              *l_niveau_courant;
                   2175:    struct_liste_variables_statiques    *l_element_statique_courant;
                   2176: 
                   2177:    struct_variable                     s_variable;
1.63      bertrand 2178:    struct_variable_statique            s_variable_statique;
1.60      bertrand 2179: 
                   2180:    unsigned char                       *ptr;
1.38      bertrand 2181: 
                   2182:    (*s_nouvel_etat_processus).s_arbre_variables = NULL;
                   2183:    (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
                   2184: 
                   2185:    l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
                   2186:    
                   2187:    // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1.47      bertrand 2188:    // 0, s'il existe est le niveau précédent la valeur courante dans la
1.38      bertrand 2189:    // boucle.
                   2190: 
                   2191:    if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
                   2192:            != 0)
                   2193:    {
                   2194:        l_niveau_courant = (*l_niveau_courant).precedent;
                   2195:    }
                   2196: 
                   2197:    // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
                   2198:    // itérations (par construction).
1.28      bertrand 2199: 
1.47      bertrand 2200:    niveau_0_traite = d_faux;
                   2201:    niveau_1_traite = d_faux;
                   2202: 
1.38      bertrand 2203:    for(i = 0; i <= 2; i++)
                   2204:    {
                   2205:        if ((*((struct_variable *) (*(*l_niveau_courant).liste)
                   2206:                .donnee)).niveau == 0)
                   2207:        {
1.47      bertrand 2208:            if (niveau_0_traite == d_faux)
                   2209:            {
                   2210:                l_element_courant = (*l_niveau_courant).liste;
1.23      bertrand 2211: 
1.47      bertrand 2212:                while(l_element_courant != NULL)
1.38      bertrand 2213:                {
1.47      bertrand 2214:                    if (ajout_variable(s_nouvel_etat_processus,
                   2215:                            (struct_variable *) (*l_element_courant).donnee)
                   2216:                            == d_erreur)
                   2217:                    {
                   2218:                        return;
                   2219:                    }
                   2220: 
                   2221:                    l_element_courant = (*l_element_courant).suivant;
1.38      bertrand 2222:                }
                   2223: 
1.47      bertrand 2224:                niveau_0_traite = d_vrai;
1.38      bertrand 2225:            }
                   2226:        }
                   2227:        else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
                   2228:                .donnee)).niveau == 1)
                   2229:        {
1.47      bertrand 2230:            if (niveau_1_traite == d_faux)
1.38      bertrand 2231:            {
1.47      bertrand 2232:                l_element_courant = (*l_niveau_courant).liste;
1.38      bertrand 2233: 
1.47      bertrand 2234:                while(l_element_courant != NULL)
1.38      bertrand 2235:                {
1.47      bertrand 2236:                    s_variable = (*((struct_variable *)
                   2237:                            (*l_element_courant).donnee));
1.38      bertrand 2238: 
1.90      bertrand 2239:                    if ((s_variable.nom = rpl_malloc(s_nouvel_etat_processus,
                   2240:                            (strlen((*((struct_variable *)
1.89      bertrand 2241:                            (*l_element_courant).donnee)).nom) + 1) *
                   2242:                            sizeof(unsigned char))) == NULL)
1.47      bertrand 2243:                    {
                   2244:                        (*s_nouvel_etat_processus).erreur_systeme =
                   2245:                                d_es_allocation_memoire;
                   2246:                        return;
                   2247:                    }
                   2248: 
1.89      bertrand 2249:                    strcpy(s_variable.nom, (*((struct_variable *)
                   2250:                            (*l_element_courant).donnee)).nom);
                   2251: 
1.47      bertrand 2252:                    if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
                   2253:                            (*((struct_variable *) (*l_element_courant).donnee))
                   2254:                            .objet, 'P')) == NULL)
                   2255:                    {
                   2256:                        (*s_nouvel_etat_processus).erreur_systeme =
                   2257:                                d_es_allocation_memoire;
                   2258:                        return;
                   2259:                    }
                   2260: 
                   2261:                    if (ajout_variable(s_nouvel_etat_processus, &s_variable)
                   2262:                            == d_erreur)
                   2263:                    {
                   2264:                        return;
                   2265:                    }
1.38      bertrand 2266: 
1.47      bertrand 2267:                    l_element_courant = (*l_element_courant).suivant;
1.38      bertrand 2268:                }
                   2269: 
1.47      bertrand 2270:                niveau_1_traite = d_vrai;
1.38      bertrand 2271:            }
                   2272: 
                   2273:            // Les variables de niveau 0 ayant déjà été copiées, on
                   2274:            // peut sortir de la boucle car toutes les variables sont
                   2275:            // maintenant disponibles dans le fil d'exécution fils.
                   2276: 
                   2277:            break;
                   2278:        }
                   2279: 
                   2280:        l_niveau_courant = (*l_niveau_courant).precedent;
                   2281:    }
                   2282: 
1.60      bertrand 2283:    // Copie des variables statiques
                   2284: 
                   2285:    l_element_statique_courant = (*s_etat_processus)
                   2286:            .l_liste_variables_statiques;
                   2287: 
                   2288:    while(l_element_statique_courant != NULL)
                   2289:    {
                   2290:        // Création des branches de l'arbre si nécessaire.
                   2291: 
                   2292:        if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
                   2293:        {
                   2294:            if (((*s_nouvel_etat_processus).s_arbre_variables =
                   2295:                        allocation_noeud(s_nouvel_etat_processus)) == NULL)
                   2296:            {
                   2297:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2298:                return;
                   2299:            }
                   2300: 
                   2301:            (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
                   2302:            (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
                   2303:                    = NULL;
                   2304:            (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
                   2305:            (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
                   2306:                    = -1;
                   2307:            (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
                   2308: 
                   2309:            if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
                   2310:                    allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
                   2311:            {
                   2312:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2313:                return;
                   2314:            }
                   2315: 
                   2316:            for(i = 0; i < (*s_nouvel_etat_processus)
                   2317:                    .nombre_caracteres_variables; i++)
                   2318:            {
                   2319:                (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
                   2320:                        = NULL;
                   2321:            }
                   2322:        }
                   2323: 
                   2324:        l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
                   2325:        ptr = (*(*l_element_statique_courant).variable).nom;
                   2326: 
                   2327:        while((*ptr) != d_code_fin_chaine)
                   2328:        {
                   2329:            BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
                   2330:                    [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
                   2331:                    (*(*l_element_statique_courant).variable).nom, *ptr));
                   2332: 
                   2333:            if ((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2334:                    .pointeurs_caracteres_variables[*ptr]] == NULL)
                   2335:            {
                   2336:                // Le noeud n'existe pas encore, on le crée et on le marque
                   2337:                // comme utilisé dans la structure parente.
                   2338: 
                   2339:                if (((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2340:                        .pointeurs_caracteres_variables[*ptr]] =
                   2341:                        allocation_noeud(s_nouvel_etat_processus)) == NULL)
                   2342:                {
                   2343:                    (*s_etat_processus).erreur_systeme =
                   2344:                            d_es_allocation_memoire;
                   2345:                    return;
                   2346:                }
                   2347: 
                   2348:                (*l_variable_courante).noeuds_utilises++;
                   2349: 
                   2350:                // La feuille est par défaut vide et aucun élément du tableau
                   2351:                // noeuds (les branches qui peuvent être issues de ce nouveau
                   2352:                // noeud) n'est encore utilisée.
                   2353: 
                   2354:                (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2355:                        .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
                   2356:                (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2357:                        .pointeurs_caracteres_variables[*ptr]]).feuille_statique
                   2358:                        = NULL;
                   2359:                (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2360:                        .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises
                   2361:                        = 0;
                   2362: 
                   2363:                // Le champ noeud_pere de la structure créée pointe sur
                   2364:                // la structure parente et l'indice tableau_pere correspond à la
                   2365:                // position réelle dans le tableau noeuds[] de la structure
                   2366:                // parente du noeud courant. Cette valeur sera utilisée lors de
                   2367:                // la destruction du noeud pour annuler le pointeur contenu dans
                   2368:                // le tableau noeuds[] de la structure parente.
                   2369: 
                   2370:                (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2371:                        .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
                   2372:                        l_variable_courante;
                   2373:                (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2374:                        .pointeurs_caracteres_variables[*ptr]])
                   2375:                        .indice_tableau_pere = (*s_nouvel_etat_processus)
                   2376:                        .pointeurs_caracteres_variables[*ptr];
                   2377: 
                   2378:                // Allocation du tableau noeuds[] et initialisation à zéro de
                   2379:                // tous les pointeurs.
                   2380: 
                   2381:                if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2382:                        .pointeurs_caracteres_variables[*ptr]]).noeuds =
                   2383:                        allocation_tableau_noeuds(s_nouvel_etat_processus))
                   2384:                        == NULL)
                   2385:                {
                   2386:                    (*s_etat_processus).erreur_systeme
                   2387:                            = d_es_allocation_memoire;
                   2388:                    return;
                   2389:                }
                   2390: 
                   2391:                for(i = 0; i < (*s_nouvel_etat_processus)
                   2392:                        .nombre_caracteres_variables; i++)
                   2393:                {
                   2394:                    (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
                   2395:                            .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                   2396:                            = NULL;
                   2397:                }
                   2398:            }
                   2399: 
                   2400:            l_variable_courante = (*l_variable_courante).noeuds
                   2401:                    [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
                   2402:                    [*ptr]];
                   2403: 
                   2404:            ptr++;
                   2405:        }
                   2406: 
1.63      bertrand 2407:        // Il faut copier la variable pour la dissocier de la variable
                   2408:        // restant dans le thread parent.
                   2409: 
                   2410:        s_variable_statique = (*(*l_element_statique_courant).variable);
                   2411: 
                   2412:        if (copie_objet(s_etat_processus, s_variable_statique.objet, 'P')
                   2413:                == NULL)
                   2414:        {
                   2415:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2416:            return;
                   2417:        }
                   2418: 
1.90      bertrand 2419:        if ((s_variable_statique.nom = rpl_malloc(s_nouvel_etat_processus,
                   2420:                (strlen((*(*l_element_statique_courant).variable).nom) + 1) *
1.63      bertrand 2421:                sizeof(unsigned char))) == NULL)
1.60      bertrand 2422:        {
                   2423:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2424:            return;
                   2425:        }
                   2426: 
1.63      bertrand 2427:        strcpy(s_variable_statique.nom, (*(*l_element_statique_courant)
                   2428:                .variable).nom);
                   2429: 
                   2430:        if (creation_variable_statique(s_nouvel_etat_processus,
                   2431:                &s_variable_statique) == d_erreur)
1.62      bertrand 2432:        {
                   2433:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2434:            return;
                   2435:        }
                   2436: 
1.60      bertrand 2437:        l_element_statique_courant = (*l_element_statique_courant).suivant;
                   2438:    }
                   2439: 
1.38      bertrand 2440:    return;
1.23      bertrand 2441: }
                   2442: 
                   2443: 
                   2444: /*
                   2445: ================================================================================
                   2446:   Procédure d'initialisation de la table de correspondance des variables
                   2447: ================================================================================
                   2448:   Entrée :
                   2449: --------------------------------------------------------------------------------
                   2450:   Sortie :
                   2451: --------------------------------------------------------------------------------
                   2452:   Effets de bord : néant
                   2453: ================================================================================
                   2454: */
                   2455: 
                   2456: /*
1.87      bertrand 2457:  * Caractères autorisés dans les variables
1.23      bertrand 2458:  *
                   2459:  * 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
                   2460:  * 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
                   2461:  * _
                   2462:  * 1 2 3 4 5 6 7 8 9 0
                   2463:  */
                   2464: 
                   2465: void
                   2466: initialisation_variables(struct_processus *s_etat_processus)
                   2467: {
                   2468:    int             decalage;
                   2469:    int             i;
                   2470:    int             longueur_tableau;
                   2471: 
                   2472:    unsigned char   caractere;
                   2473: 
                   2474:    // Récupération de la longueur d'un unsigned char
                   2475: 
                   2476:    longueur_tableau = 1;
                   2477:    decalage = 0;
                   2478:    caractere = 1;
                   2479: 
                   2480:    while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
                   2481:    {
                   2482:        decalage++;
                   2483:        longueur_tableau *= 2;
                   2484:    }
                   2485: 
                   2486:    if (((*s_etat_processus).pointeurs_caracteres_variables =
1.70      bertrand 2487:            malloc(((size_t) longueur_tableau) * sizeof(int))) == NULL)
1.23      bertrand 2488:    {
                   2489:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2490:        return;
                   2491:    }
                   2492: 
                   2493:    for(i = 0; i < longueur_tableau; i++)
                   2494:    {
                   2495:        (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
                   2496:    }
                   2497: 
                   2498:    (*s_etat_processus).nombre_caracteres_variables = 0;
                   2499: 
                   2500: #define DECLARATION_CARACTERE(c) \
                   2501:        do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
                   2502:        (*s_etat_processus).nombre_caracteres_variables++; } while(0)
                   2503: 
                   2504:    DECLARATION_CARACTERE('A');
                   2505:    DECLARATION_CARACTERE('B');
                   2506:    DECLARATION_CARACTERE('C');
                   2507:    DECLARATION_CARACTERE('D');
                   2508:    DECLARATION_CARACTERE('E');
                   2509:    DECLARATION_CARACTERE('F');
                   2510:    DECLARATION_CARACTERE('G');
                   2511:    DECLARATION_CARACTERE('H');
                   2512:    DECLARATION_CARACTERE('I');
                   2513:    DECLARATION_CARACTERE('J');
                   2514:    DECLARATION_CARACTERE('K');
                   2515:    DECLARATION_CARACTERE('L');
                   2516:    DECLARATION_CARACTERE('M');
                   2517:    DECLARATION_CARACTERE('N');
                   2518:    DECLARATION_CARACTERE('O');
                   2519:    DECLARATION_CARACTERE('P');
                   2520:    DECLARATION_CARACTERE('Q');
                   2521:    DECLARATION_CARACTERE('R');
                   2522:    DECLARATION_CARACTERE('S');
                   2523:    DECLARATION_CARACTERE('T');
                   2524:    DECLARATION_CARACTERE('U');
                   2525:    DECLARATION_CARACTERE('V');
                   2526:    DECLARATION_CARACTERE('W');
                   2527:    DECLARATION_CARACTERE('X');
                   2528:    DECLARATION_CARACTERE('Y');
                   2529:    DECLARATION_CARACTERE('Z');
                   2530: 
                   2531:    DECLARATION_CARACTERE('a');
                   2532:    DECLARATION_CARACTERE('b');
                   2533:    DECLARATION_CARACTERE('c');
                   2534:    DECLARATION_CARACTERE('d');
                   2535:    DECLARATION_CARACTERE('e');
                   2536:    DECLARATION_CARACTERE('f');
                   2537:    DECLARATION_CARACTERE('g');
                   2538:    DECLARATION_CARACTERE('h');
                   2539:    DECLARATION_CARACTERE('i');
                   2540:    DECLARATION_CARACTERE('j');
                   2541:    DECLARATION_CARACTERE('k');
                   2542:    DECLARATION_CARACTERE('l');
                   2543:    DECLARATION_CARACTERE('m');
                   2544:    DECLARATION_CARACTERE('n');
                   2545:    DECLARATION_CARACTERE('o');
                   2546:    DECLARATION_CARACTERE('p');
                   2547:    DECLARATION_CARACTERE('q');
                   2548:    DECLARATION_CARACTERE('r');
                   2549:    DECLARATION_CARACTERE('s');
                   2550:    DECLARATION_CARACTERE('t');
                   2551:    DECLARATION_CARACTERE('u');
                   2552:    DECLARATION_CARACTERE('v');
                   2553:    DECLARATION_CARACTERE('w');
                   2554:    DECLARATION_CARACTERE('x');
                   2555:    DECLARATION_CARACTERE('y');
                   2556:    DECLARATION_CARACTERE('z');
                   2557: 
                   2558:    DECLARATION_CARACTERE('_');
                   2559: 
                   2560:    DECLARATION_CARACTERE('1');
                   2561:    DECLARATION_CARACTERE('2');
                   2562:    DECLARATION_CARACTERE('3');
                   2563:    DECLARATION_CARACTERE('4');
                   2564:    DECLARATION_CARACTERE('5');
                   2565:    DECLARATION_CARACTERE('6');
                   2566:    DECLARATION_CARACTERE('7');
                   2567:    DECLARATION_CARACTERE('8');
                   2568:    DECLARATION_CARACTERE('9');
                   2569:    DECLARATION_CARACTERE('0');
                   2570: #undef DECLARATION_CARACTERE
                   2571: 
                   2572:    return;
                   2573: }
1.25      bertrand 2574: 
1.1       bertrand 2575: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>