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

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

CVSweb interface <joel.bertrand@systella.fr>