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

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

CVSweb interface <joel.bertrand@systella.fr>