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

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

CVSweb interface <joel.bertrand@systella.fr>