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

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

CVSweb interface <joel.bertrand@systella.fr>