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

1.1       bertrand    1: /*
                      2: ================================================================================
1.21      bertrand    3:   RPL/2 (R) version 4.1.0.prerelease.0
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: ================================================================================
                     28:   Routine de création d'une nouvelle variable
                     29:   Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.
                     30:   Dans le cas 'V', la variable est volatile.
                     31:   Dans le cas 'S', elle est statique.
                     32:   Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.
                     33:   Dans le cas 'P', la variable est privée.
                     34:   Dans le cas 'S', elle est partagée.
                     35: --------------------------------------------------------------------------------
                     36:   Sortie :
                     37: --------------------------------------------------------------------------------
                     38:   Effets de bords : néant
                     39: ================================================================================
                     40: */
                     41: 
1.25    ! bertrand   42: static logical1
        !            43: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1       bertrand   44: {
1.25    ! bertrand   45:    int                         i;
        !            46: 
        !            47:    struct_arbre_variables      *l_variable_courante;
1.12      bertrand   48: 
1.25    ! bertrand   49:    struct_liste_variables      *l_nouvelle_variable;
        !            50:    struct_liste_variables      *l_variable_candidate;
1.1       bertrand   51: 
1.25    ! bertrand   52:    struct_liste_chainee        *l_nouvel_element;
1.1       bertrand   53: 
1.25    ! bertrand   54:    unsigned char               *ptr;
1.1       bertrand   55: 
1.25    ! bertrand   56:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand   57:    {
1.25    ! bertrand   58:        if (((*s_etat_processus).s_arbre_variables =
        !            59:                malloc(sizeof(struct_arbre_variables))) == NULL)
        !            60:        {
        !            61:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            62:            return(d_erreur);
        !            63:        }
        !            64: 
        !            65:        (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
        !            66:        (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.1       bertrand   67: 
1.25    ! bertrand   68:        if (((*(*s_etat_processus).arbre_instructions).noeud =
        !            69:                malloc((*s_etat_processus).nombre_caracteres_variables
        !            70:                * sizeof(struct_arbre_variables))) == NULL)
1.1       bertrand   71:        {
1.25    ! bertrand   72:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            73:            return(d_erreur);
        !            74:        }
        !            75: 
        !            76:        for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
        !            77:        {
        !            78:            (*(*s_etat_processus).s_arbre_variables).noeud[i] = NULL;
        !            79:        }
        !            80:    }
        !            81: 
        !            82:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
        !            83:    ptr = (*s_variable).nom;
        !            84: 
        !            85:    while((*ptr) != d_code_fin_chaine)
        !            86:    {
        !            87:        BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
        !            88:                printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
        !            89:                *ptr));
        !            90: 
        !            91:        if ((*l_variable_courante).noeud[(*s_etat_processus)
        !            92:                .pointeurs_caracteres_variables[*ptr]] == NULL)
        !            93:        {
        !            94:            // Le noeud n'existe pas encore, on le crée.
        !            95: 
        !            96:            if (((*l_variable_courante).noeud[(*s_etat_processus)
        !            97:                    .pointeurs_caracteres_variables[*ptr]] =
        !            98:                    malloc(sizeof(struct_arbre_variables))) == NULL)
        !            99:            {
        !           100:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           101:                return(d_erreur);
        !           102:            }
        !           103: 
        !           104:            (*(*l_variable_courante).noeud[(*s_etat_processus)
        !           105:                    .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
        !           106:            (*(*l_variable_courante).noeud[(*s_etat_processus)
        !           107:                    .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
        !           108: 
        !           109:            if (((*(*l_variable_courante).noeud[(*s_etat_processus)
        !           110:                    .pointeurs_caracteres_variables[*ptr]]).noeud =
        !           111:                    malloc((*s_etat_processus).nombre_caracteres_variables
        !           112:                    * sizeof(struct_arbre_variables))) == NULL)
        !           113:            {
        !           114:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           115:                return(d_erreur);
        !           116:            }
        !           117: 
        !           118:            for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
        !           119:            {
        !           120:                (*(*l_variable_courante).noeud[(*s_etat_processus)
        !           121:                        .pointeurs_caracteres_variables[*ptr]]).noeud[i] = NULL;
        !           122:            }
        !           123:        }
        !           124: 
        !           125:        (*l_variable_courante).noeuds_utilises++;
        !           126:        l_variable_courante = (*l_variable_courante).noeud
        !           127:                [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
        !           128:        ptr++;
        !           129:    }
        !           130: 
        !           131:    if ((*l_variable_courante).feuille == NULL)
        !           132:    {
        !           133:        // Aucune variable de même nom préexiste. On alloue le premier
        !           134:        // élément de la liste doublement chaînée contenant toutes les
        !           135:        // variables de même nom. Cette liste boucle en premier lieu sur
        !           136:        // elle-même.
        !           137: 
        !           138:        if (((*l_variable_courante).feuille = malloc(
        !           139:                sizeof(struct_liste_variables))) == NULL)
        !           140:        {
        !           141:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           142:            return(d_erreur);
        !           143:        }
        !           144: 
        !           145:        (*(*l_variable_courante).feuille).suivant =
        !           146:                (*l_variable_courante).feuille;
        !           147:        (*(*l_variable_courante).feuille).precedent =
        !           148:                (*l_variable_courante).feuille;
        !           149: 
        !           150:        // Allocation de la variable sur l'élément de la liste.
        !           151: 
        !           152:        if (((*(*l_variable_courante).feuille).variable =
        !           153:                malloc(sizeof(struct_variable))) == NULL)
        !           154:        { 
        !           155:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           156:            return(d_erreur);
        !           157:        }
        !           158: 
        !           159:        (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
        !           160:                (*s_variable);
        !           161: 
        !           162:        if (((*((struct_variable *) (*(*l_variable_courante).feuille).variable))
        !           163:                .nom = strdup((*s_variable).nom)) == NULL)
        !           164:        {
        !           165:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           166:            return(d_erreur);
        !           167:        }
        !           168:    }
        !           169:    else
        !           170:    {
        !           171:        if ((*s_variable).niveau > 1)
        !           172:        {
        !           173:            // Cas d'une variable locale
        !           174: 
        !           175:            // Si le niveau de la dernière variable de même nom est
        !           176:            // supérieur au niveau de la variable locale que l'on veut
        !           177:            // enregistrer dans la liste, cette liste est incohérente.
        !           178: 
        !           179:            BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
        !           180:                    (*s_variable).niveau,
        !           181:                    printf("Variable=\"%s\"\n", (*s_variable).nom));
        !           182: 
        !           183:            // On ajoute la variable à la liste existante.
        !           184: 
        !           185:            if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
        !           186:                    == NULL)
        !           187:            {
        !           188:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           189:                return(d_erreur);
        !           190:            }
        !           191: 
        !           192:            (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
        !           193:            (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
        !           194:                    .precedent;
        !           195:            (*(*(*l_variable_courante).feuille).precedent).suivant =
        !           196:                    l_nouvelle_variable;
        !           197:            (*(*l_variable_courante).feuille).precedent =
        !           198:                    l_nouvelle_variable;
        !           199:            (*l_variable_courante).feuille = l_nouvelle_variable;
        !           200: 
        !           201:            if (((*(*l_variable_courante).feuille).variable =
        !           202:                    malloc(sizeof(struct_variable))) == NULL)
        !           203:            { 
        !           204:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           205:                return(d_erreur);
        !           206:            }
        !           207: 
        !           208:            (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
        !           209:                    = (*s_variable);
        !           210: 
        !           211:            if (((*((struct_variable *) (*(*l_variable_courante).feuille)
        !           212:                    .variable)).nom = strdup((*s_variable).nom)) == NULL)
        !           213:            {
        !           214:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           215:                return(d_erreur);
        !           216:            }
1.1       bertrand  217:        }
                    218:        else
                    219:        {
1.25    ! bertrand  220:            // Cas d'une variable globale (niveau 0 [définitions] ou 1
        !           221:            // [variables globales])
        !           222: 
        !           223:            l_variable_candidate = (*l_variable_courante).feuille;
        !           224: 
        !           225:            do
        !           226:            {
        !           227:                // S'il y a déjà une variable de même niveau, la pile
        !           228:                // est incohérente.
        !           229: 
        !           230:                BUG((*(*l_variable_candidate).variable).niveau ==
        !           231:                        (*s_variable).niveau,
        !           232:                        printf("Variable=\"%s\"\n", (*s_variable).nom));
        !           233: 
        !           234:                l_variable_candidate = (*l_variable_candidate).precedent;
        !           235:            } while((l_variable_candidate != (*l_variable_courante).feuille) &&
        !           236:                    ((*(*l_variable_candidate).variable).niveau <= 1));
        !           237: 
        !           238:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
        !           239:                    .niveau > 1)
        !           240:            {
        !           241:                // Ajout inconditionnel des variables de niveaux 0 et 1
        !           242:            }
        !           243:            else
1.1       bertrand  244:            {
1.25    ! bertrand  245:                l_variable_candidate = (*(*l_variable_courante).feuille)
        !           246:                        .precedent;
        !           247:            }
        !           248: 
        !           249:            (*l_nouvelle_variable).suivant = l_variable_candidate;
        !           250:            (*l_nouvelle_variable).precedent = (*l_variable_candidate)
        !           251:                    .precedent;
        !           252:            (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
        !           253:            (*l_variable_candidate).precedent = l_nouvelle_variable;
        !           254: 
        !           255:            if (((*l_nouvelle_variable).variable =
        !           256:                    malloc(sizeof(struct_variable))) == NULL)
        !           257:            { 
        !           258:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           259:                return(d_erreur);
        !           260:            }
        !           261: 
        !           262:            (*(*l_nouvelle_variable).variable) = (*s_variable);
        !           263: 
        !           264:            if (((*(*l_nouvelle_variable).variable).nom =
        !           265:                    strdup((*s_variable).nom)) == NULL)
        !           266:            {
        !           267:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           268:                return(d_erreur);
1.1       bertrand  269:            }
                    270:        }
1.25    ! bertrand  271:    }
        !           272: 
        !           273:    // Ajout de la variable nouvellement créée à la liste par niveaux.
        !           274:    // Le pointeur contenu dans la structure de description du processus indique
        !           275:    // toujours le plus haut niveau utilisé.
        !           276: 
        !           277:    if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
        !           278:    {
        !           279:        // Le niveau courant n'existe pas. Il est créé.
        !           280: 
        !           281:        if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
        !           282:                == NULL)
        !           283:        {
        !           284:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           285:            return(d_erreur);
        !           286:        }
        !           287: 
        !           288:        (*l_nouvelle_variable).suivant = l_nouvelle_variable;
        !           289:        (*l_nouvelle_variable).precedent = l_nouvelle_variable;
        !           290: 
        !           291:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
        !           292:    }
        !           293:    else if ((*s_variable).niveau > (*((struct_variable *)
        !           294:            (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
        !           295:            .donnee)).niveau)
        !           296:    {
        !           297:        // Le niveau courant n'existe pas. Il est créé.
1.1       bertrand  298: 
1.25    ! bertrand  299:        if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
        !           300:                == NULL)
1.1       bertrand  301:        {
                    302:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    303:            return(d_erreur);
                    304:        }
                    305: 
1.25    ! bertrand  306:        (*l_nouvelle_variable).suivant = (*s_etat_processus)
        !           307:                .l_liste_variables_par_niveau;
        !           308:        (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
        !           309:                .l_liste_variables_par_niveau).precedent;
        !           310:        (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
        !           311:                .suivant = l_nouvelle_variable;
        !           312:        (*(*s_etat_processus).l_liste_variables_par_niveau).precedent =
        !           313:                l_nouvelle_variable;
        !           314: 
        !           315:        (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
        !           316:    }
        !           317:    else
        !           318:    {
        !           319:        // Création d'une variable de niveau 0 ou 1
        !           320: 
        !           321:        l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
        !           322: 
        !           323:        if ((*((struct_variable *) (*(*(*(*s_etat_processus)
        !           324:                .l_liste_variables_par_niveau).precedent).liste).donnee))
        !           325:                .niveau > 1)
        !           326:        {
        !           327:            // Ajout inconditionnel des variables de niveaux 0 et 1
        !           328:        }
        !           329:        else
        !           330:        {
        !           331:            l_variable_candidate = (*(*s_etat_processus)
        !           332:                    .l_liste_variables_par_niveau).precedent;
        !           333:        }
        !           334: 
        !           335:        (*l_nouvelle_variable).suivant = l_variable_candidate;
        !           336:        (*l_nouvelle_variable).precedent = (*l_variable_candidate)
        !           337:                .precedent;
        !           338:        (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
        !           339:        (*l_variable_candidate).precedent = l_nouvelle_variable;
        !           340:    }
        !           341: 
        !           342:    // Ajout de la variable en tête de la liste
        !           343: 
        !           344:    if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
        !           345:    {
        !           346:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           347:        return(d_erreur);
1.1       bertrand  348:    }
                    349: 
1.25    ! bertrand  350:    (*l_nouvel_element).suivant = (*(*s_etat_processus)
        !           351:            .l_liste_variables_par_niveau).liste;
        !           352:    (*l_nouvel_element).donnee = (struct_objet *) s_variable;
        !           353:    (*l_nouvelle_variable).liste = l_nouvel_element;
        !           354: 
        !           355:    return(d_absence_erreur);
        !           356: }
        !           357: 
        !           358: logical1
        !           359: creation_variable(struct_processus *s_etat_processus,
        !           360:        struct_variable *s_variable,
        !           361:        unsigned char autorisation_creation_variable_statique,
        !           362:        unsigned char autorisation_creation_variable_partagee)
        !           363: {
1.1       bertrand  364:    if ((*s_etat_processus).mode_execution_programme == 'Y')
                    365:    {
                    366:        (*s_variable).origine = 'P';
                    367:    }
                    368:    else
                    369:    {
                    370:        (*s_variable).origine = 'E';
                    371:    }
                    372: 
                    373:    if ((*s_variable).niveau == 0)
                    374:    {
                    375:        // Un point d'entrée de définition est verrouillé.
                    376: 
                    377:        if ((*s_variable).origine == 'P')
                    378:        {
                    379:            (*s_variable).variable_statique.adresse = 0;
                    380:            (*s_variable).variable_partagee.adresse = 0;
                    381:        }
                    382:        else
                    383:        {
                    384:            (*s_variable).variable_statique.pointeur = NULL;
                    385:            (*s_variable).variable_partagee.pointeur = NULL;
                    386:        }
                    387: 
                    388:        (*s_variable).variable_verrouillee = d_vrai;
                    389:    }
                    390:    else if ((*s_variable).niveau == 1)
                    391:    {
                    392:        // Une variable globale ne peut être statique.
                    393: 
                    394:        if ((*s_variable).origine == 'P')
                    395:        {
                    396:            (*s_variable).variable_statique.adresse = 0;
                    397:            (*s_variable).variable_partagee.adresse = 0;
                    398:        }
                    399:        else
                    400:        {
                    401:            (*s_variable).variable_statique.pointeur = NULL;
                    402:            (*s_variable).variable_partagee.pointeur = NULL;
                    403:        }
                    404: 
                    405:        (*s_variable).variable_verrouillee = d_faux;
                    406:    }
                    407:    else
                    408:    {
                    409:        // 0 -> variable volatile
                    410:        // adresse de création -> variable statique
                    411: 
                    412:        if (autorisation_creation_variable_statique == 'V')
                    413:        {
                    414:            if (autorisation_creation_variable_partagee == 'S')
                    415:            {
                    416:                // On force la création d'une variable partagée
                    417: 
                    418:                if ((*s_variable).origine == 'P')
                    419:                {
                    420:                    (*s_variable).variable_statique.adresse = 0;
                    421:                    (*s_variable).variable_partagee.adresse =
                    422:                            (*s_etat_processus).position_courante;
                    423:                }
                    424:                else
                    425:                {
                    426:                    (*s_variable).variable_statique.pointeur = NULL;
                    427:                    (*s_variable).variable_partagee.pointeur =
                    428:                            (*s_etat_processus).objet_courant;
                    429:                }
                    430:            }
                    431:            else
                    432:            {
                    433:                // On force la création d'une variable volatile
                    434: 
                    435:                if ((*s_variable).origine == 'P')
                    436:                {
                    437:                    (*s_variable).variable_statique.adresse = 0;
                    438:                    (*s_variable).variable_partagee.adresse = 0;
                    439:                }
                    440:                else
                    441:                {
                    442:                    (*s_variable).variable_statique.pointeur = NULL;
                    443:                    (*s_variable).variable_partagee.pointeur = NULL;
                    444:                }
                    445:            }
                    446:        }
                    447:        else
                    448:        {
                    449:            // On force la création d'une variable statique.
                    450: 
                    451:            if ((*s_variable).origine == 'P')
                    452:            {
                    453:                (*s_variable).variable_statique.adresse =
                    454:                        (*s_etat_processus).position_courante;
                    455:                (*s_variable).variable_partagee.adresse = 0;
                    456:            }
                    457:            else
                    458:            {
                    459:                (*s_variable).variable_statique.pointeur =
                    460:                        (*s_etat_processus).objet_courant;
                    461:                (*s_variable).variable_partagee.pointeur = 0;
                    462:            }
                    463:        }
                    464: 
                    465:        (*s_variable).variable_verrouillee = d_faux;
                    466:    }
                    467: 
                    468:    /*
1.25    ! bertrand  469:     * Recherche de la feuille correspondante dans l'arbre des variables.
        !           470:     * Si cette feuille n'existe pas, elle est créée.
1.1       bertrand  471:     */
                    472: 
1.25    ! bertrand  473:    if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
        !           474:    {
        !           475:        return(d_erreur);
        !           476:    }
        !           477: 
        !           478:    return(d_absence_erreur);
        !           479: }
        !           480: 
        !           481: 
        !           482: /*
        !           483: ================================================================================
        !           484:   Procédure de recherche d'une variable par son nom dans la base
        !           485: ================================================================================
        !           486:   Entrée :
        !           487: --------------------------------------------------------------------------------
        !           488:   Sortie :
        !           489: --------------------------------------------------------------------------------
        !           490:   Effets de bord : néant
        !           491: ================================================================================
        !           492: */
        !           493: 
        !           494: logical1
        !           495: recherche_variable(struct_processus *s_etat_processus,
        !           496:        unsigned char *nom_variable)
        !           497: {
        !           498:    int                         pointeur;
        !           499: 
        !           500:    struct_arbre_variables      *l_variable_courante;
        !           501:    struct_liste_pile_systeme   *l_element_courant;
        !           502: 
        !           503:    unsigned char               *ptr;
        !           504: 
        !           505:    unsigned long               niveau_appel;
1.1       bertrand  506: 
1.25    ! bertrand  507:    if ((*s_etat_processus).s_arbre_variables == NULL)
1.1       bertrand  508:    {
1.25    ! bertrand  509:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
        !           510:        return d_faux;
1.1       bertrand  511:    }
1.25    ! bertrand  512: 
        !           513:    ptr = nom_variable;
        !           514: 
        !           515:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand  516:    {
1.25    ! bertrand  517:        pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
        !           518: 
        !           519:        if (pointeur < 0)
        !           520:        {
        !           521:            // Caractère hors de l'alphabet des variables
        !           522:            return(d_erreur);
        !           523:        }
        !           524: 
        !           525:        if ((*l_variable_courante).noeud[pointeur] == NULL)
1.1       bertrand  526:        {
1.25    ! bertrand  527:            // Le chemin de la variable candidate n'existe pas.
        !           528:            return(d_erreur);
1.1       bertrand  529:        }
                    530: 
1.25    ! bertrand  531:        l_variable_courante = (*l_variable_courante).noeud[pointeur];
        !           532:        ptr++;
        !           533:    }
        !           534: 
        !           535:    if ((*l_variable_courante).feuille != NULL)
        !           536:    {
        !           537:        // Il existe une pile de variables de même nom. Le sommet de la
        !           538:        // pile est la variable de niveau le plus haut.
        !           539: 
        !           540:        l_element_courant = (*s_etat_processus).l_base_pile_systeme;
        !           541: 
        !           542:        if (l_element_courant == NULL)
1.12      bertrand  543:        {
1.25    ! bertrand  544:            // Problème : la pile système est vide !
        !           545:            (*s_etat_processus).erreur_systeme = d_es_pile_vide;
        !           546:            return(d_erreur);
1.12      bertrand  547:        }
1.25    ! bertrand  548: 
        !           549:        while((*l_element_courant).retour_definition != 'Y')
1.12      bertrand  550:        {
1.25    ! bertrand  551:            l_element_courant = (*l_element_courant).suivant;
1.12      bertrand  552: 
1.25    ! bertrand  553:            if (l_element_courant == NULL)
1.12      bertrand  554:            {
1.25    ! bertrand  555:                (*s_etat_processus).erreur_systeme = d_es_pile_vide;
        !           556:                return(d_erreur);
1.12      bertrand  557:            }
1.25    ! bertrand  558:        }
        !           559: 
        !           560:        niveau_appel = (*l_element_courant).niveau_courant;
1.12      bertrand  561: 
1.25    ! bertrand  562:        if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
        !           563:        {
        !           564:            // Une variable locale est accessible puisque créée dans la
        !           565:            // fonction courante.
        !           566: 
        !           567:            (*s_etat_processus).pointeur_variable_courante =
        !           568:                    (*(*l_variable_courante).feuille).variable;
        !           569:            (*s_etat_processus).pointeur_feuille_courante =
        !           570:                    (*l_variable_courante).feuille;
        !           571:            return(d_absence_erreur);
        !           572:        }
        !           573:        else
        !           574:        {
        !           575:            // Aucune variable locale n'est accessible depuis la fonction.
        !           576:            // Dans ce cas, on prend la variable de niveau le plus bas
        !           577:            // si ce niveau est inférieur ou égal à 1 (variable globale
        !           578:            // ou fonction définie par l'utilisateur). Si le niveau de la
        !           579:            // plus ancienne variable est strictement supérieur à 1, el
        !           580:            // s'agit d'une variable locale inaccessible.
        !           581: 
        !           582:            if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
        !           583:                    .niveau <= 1)
        !           584:            {
        !           585:                (*s_etat_processus).pointeur_variable_courante =
        !           586:                        (*(*(*l_variable_courante).feuille).precedent).variable;
        !           587:                (*s_etat_processus).pointeur_feuille_courante =
        !           588:                        (*l_variable_courante).feuille;
        !           589:                return(d_absence_erreur);
1.12      bertrand  590:            }
                    591:        }
1.1       bertrand  592:    }
                    593: 
1.25    ! bertrand  594:    return(d_erreur);
1.1       bertrand  595: }
                    596: 
                    597: 
                    598: /*
                    599: ================================================================================
                    600:   Procédure de retrait d'une variable de la base
                    601: ================================================================================
                    602:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
                    603:            les globales) ou strictement globale.
                    604: --------------------------------------------------------------------------------
                    605:   Sortie :
                    606: --------------------------------------------------------------------------------
                    607:   Effets de bord : néant
                    608: ================================================================================
                    609: */
                    610: 
                    611: logical1
                    612: retrait_variable(struct_processus *s_etat_processus,
                    613:        unsigned char *nom_variable, unsigned char type)
                    614: {
                    615:    logical1            erreur;
                    616: 
                    617:    if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
                    618:    {
1.25    ! bertrand  619:        // Une variable correspondant au nom recherché est accessible.
        !           620: 
1.1       bertrand  621:        if (type == 'G')
                    622:        {
1.25    ! bertrand  623:            if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
        !           624:            {
        !           625:                // La variable obtenue est une variable locale. il faut
        !           626:                // s'assurer qu'il existe une variable de niveau 1 de même
        !           627:                // nom sur la feuille.
        !           628:            }
        !           629: 
1.1       bertrand  630:            if ((*s_etat_processus).position_variable_courante > 0)
                    631:            {
                    632:                while(strcmp((*s_etat_processus).s_liste_variables
                    633:                        [(*s_etat_processus).position_variable_courante]
                    634:                        .nom, nom_variable) == 0)
                    635:                {
                    636:                    (*s_etat_processus).position_variable_courante--;
                    637: 
                    638:                    if ((*s_etat_processus).position_variable_courante >=
                    639:                            (*s_etat_processus).nombre_variables)
                    640:                    {
                    641:                        erreur = d_erreur;
                    642:                        (*s_etat_processus).erreur_execution =
                    643:                                d_ex_variable_non_definie;
                    644:                        return erreur;
                    645:                    }
                    646:                }
                    647: 
                    648:                (*s_etat_processus).position_variable_courante++;
                    649:            }
                    650: 
                    651:            if ((*s_etat_processus).s_liste_variables
                    652:                    [(*s_etat_processus).position_variable_courante]
                    653:                    .niveau != 1)
                    654:            {
                    655:                erreur = d_erreur;
                    656:                (*s_etat_processus).erreur_execution =
                    657:                        d_ex_variable_non_definie;
                    658:                return erreur;
                    659:            }
                    660: 
                    661:            if ((*s_etat_processus).s_liste_variables
                    662:                    [(*s_etat_processus).position_variable_courante]
                    663:                    .variable_verrouillee == d_vrai)
                    664:            {
                    665:                erreur = d_erreur;
                    666:                (*s_etat_processus).erreur_execution =
                    667:                        d_ex_variable_verrouillee;
                    668:                return erreur;
                    669:            }
                    670:        }
                    671: 
                    672:        if ((*s_etat_processus).nombre_variables <
                    673:                ((*s_etat_processus).nombre_variables_allouees / 2))
                    674:        {
                    675:            (*s_etat_processus).nombre_variables_allouees /= 2;
                    676: 
                    677:            // (*s_etat_processus).nombre_variables est forcément
                    678:            // supérieur à 1 (la décrémentation est postérieure). Ce test
                    679:            // est vrai lorsque le nombre de variables allouées est
                    680:            // strictement supérieur à 2.
                    681: 
                    682:            if ((s_nouvelle_base =
                    683:                    realloc((*s_etat_processus).s_liste_variables,
                    684:                    (*s_etat_processus).nombre_variables_allouees *
                    685:                    sizeof(struct_variable))) == NULL)
                    686:            {
                    687:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    688:                return(d_erreur);
                    689:            }
                    690: 
                    691:            (*s_etat_processus).s_liste_variables = s_nouvelle_base;
                    692:        }
                    693: 
                    694:        position_supprimee = (*s_etat_processus).position_variable_courante;
                    695: 
                    696:        liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
                    697:                [position_supprimee].objet);
                    698:        free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
                    699: 
                    700:        (*s_etat_processus).nombre_variables--;
                    701: 
                    702:        for(position_courante = position_supprimee;
                    703:                position_courante < (*s_etat_processus).nombre_variables;
                    704:                position_courante++)
                    705:        {
                    706:            (*s_etat_processus).s_liste_variables[position_courante] =
                    707:                    (*s_etat_processus).s_liste_variables
                    708:                    [position_courante + 1];
                    709:        }
                    710: 
                    711:        erreur = d_absence_erreur;
                    712:    }
                    713:    else
                    714:    {
1.25    ! bertrand  715:        // Aucune variable n'est accessible depuis le point courant du
        !           716:        // programme.
        !           717: 
1.1       bertrand  718:        erreur = d_erreur;
                    719:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    720:    }
                    721: 
1.25    ! bertrand  722:    return(erreur);
1.1       bertrand  723: }
                    724: 
                    725: 
                    726: /*
                    727: ================================================================================
                    728:   Procédure de retrait des variables de niveau strictement supérieur au
                    729:   niveau courant
                    730: ================================================================================
                    731:   Entrée :
                    732: --------------------------------------------------------------------------------
                    733:   Sortie :
                    734: --------------------------------------------------------------------------------
                    735:   Effets de bord : néant
                    736: ================================================================================
                    737: */
                    738: 
                    739: logical1
                    740: retrait_variable_par_niveau(struct_processus *s_etat_processus)
                    741: {
                    742:    unsigned long                   i;
                    743:    unsigned long                   j;
                    744: 
                    745:    struct_variable                 *tampon;
                    746: 
                    747:    for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
                    748:    {
                    749:        if ((*s_etat_processus).s_liste_variables[i].niveau <=
                    750:                (*s_etat_processus).niveau_courant)
                    751:        {
                    752:            (*s_etat_processus).s_liste_variables[j++] =
                    753:                    (*s_etat_processus).s_liste_variables[i];
                    754:        }
                    755:        else
                    756:        {
                    757:            if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
                    758:            {
                    759:                if ((*s_etat_processus).s_liste_variables[i]
                    760:                        .variable_statique.adresse != 0)
                    761:                {
                    762:                    /*
                    763:                     * Gestion des variables statiques
                    764:                     */
                    765: 
                    766:                    if (recherche_variable_statique(s_etat_processus,
                    767:                            (*s_etat_processus).s_liste_variables[i]
                    768:                            .nom, (*s_etat_processus).s_liste_variables
                    769:                            [i].variable_statique, ((*s_etat_processus)
                    770:                            .mode_execution_programme
                    771:                             == 'Y') ? 'P' : 'E') == d_vrai)
                    772:                    {
                    773:                        (*s_etat_processus).s_liste_variables_statiques
                    774:                                [(*s_etat_processus)
                    775:                                .position_variable_statique_courante]
                    776:                                .objet = (*s_etat_processus)
                    777:                                .s_liste_variables[i].objet;
                    778:                    }
                    779:                    else
                    780:                    {
                    781:                        (*s_etat_processus).erreur_systeme =
                    782:                                d_es_variable_introuvable;
                    783:                    }
                    784: 
                    785:                    (*s_etat_processus).s_liste_variables[i].objet = NULL;
                    786:                }
                    787:            }
                    788:            else
                    789:            {
                    790:                if ((*s_etat_processus).s_liste_variables[i]
                    791:                        .variable_statique.pointeur != NULL)
                    792:                {
                    793:                    /*
                    794:                     * Gestion des variables statiques
                    795:                     */
                    796: 
                    797:                    if (recherche_variable_statique(s_etat_processus,
                    798:                            (*s_etat_processus).s_liste_variables[i]
                    799:                            .nom, (*s_etat_processus).s_liste_variables[i]
                    800:                            .variable_statique, ((*s_etat_processus)
                    801:                            .mode_execution_programme
                    802:                             == 'Y') ? 'P' : 'E') == d_vrai)
                    803:                    {
                    804:                        (*s_etat_processus).s_liste_variables_statiques
                    805:                                [(*s_etat_processus)
                    806:                                .position_variable_statique_courante]
                    807:                                .objet = (*s_etat_processus)
                    808:                                .s_liste_variables[i].objet;
                    809:                    }
                    810:                    else
                    811:                    {
                    812:                        (*s_etat_processus).erreur_systeme =
                    813:                                d_es_variable_introuvable;
1.22      bertrand  814:                        return(d_erreur);
1.1       bertrand  815:                    }
                    816: 
                    817:                    (*s_etat_processus).s_liste_variables[i].objet = NULL;
                    818:                }
                    819:            }
                    820: 
                    821:            free((*s_etat_processus).s_liste_variables[i].nom);
                    822:            liberation(s_etat_processus,
                    823:                    (*s_etat_processus).s_liste_variables[i].objet);
                    824:        }
                    825:    }
                    826: 
                    827:    (*s_etat_processus).nombre_variables = j;
                    828: 
                    829:    if ((*s_etat_processus).nombre_variables <
                    830:            ((*s_etat_processus).nombre_variables_allouees / 2))
                    831:    {
                    832:        (*s_etat_processus).nombre_variables_allouees /= 2;
                    833: 
                    834:        if ((tampon = realloc((*s_etat_processus).s_liste_variables,
                    835:                (*s_etat_processus).nombre_variables_allouees *
                    836:                sizeof(struct_variable))) == NULL)
                    837:        {
                    838:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    839:            return(d_erreur);
                    840:        }
                    841: 
                    842:        (*s_etat_processus).s_liste_variables = tampon;
                    843:    }
                    844: 
                    845:    return(d_absence_erreur);
                    846: }
                    847: 
1.23      bertrand  848: 
                    849: /*
                    850: ================================================================================
1.24      bertrand  851:   Procédure de retrait des toutes les variables locales et globales
                    852: ================================================================================
                    853:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
                    854:            de niveau 0)
                    855: --------------------------------------------------------------------------------
                    856:   Sortie :
                    857: --------------------------------------------------------------------------------
                    858:   Effets de bord : néant
                    859: ================================================================================
                    860: */
                    861: 
                    862: void
                    863: liberation_arbre_variables(struct_processus *s_etat_processus,
                    864:        struct_arbre_variables *arbre, logical1 retrait_definitions)
                    865: {
                    866:    int                     i;
                    867: 
                    868:    struct_liste_chainee    *l_element_courant;
                    869:    struct_liste_chainee    *l_element_suivant;
                    870: 
                    871:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    872:    {
                    873:        if ((*arbre).noeud[i] != NULL)
                    874:        {
                    875:            l_element_courant = (*arbre).l_variables;
                    876: 
                    877:            while(l_element_courant != NULL)
                    878:            {
                    879:                l_element_suivant = (*l_element_courant).suivant;
                    880: 
                    881:                if (retrait_definitions == d_vrai)
                    882:                {
                    883:                    liberation(s_etat_processus, (*((struct_variable *)
                    884:                            (*l_element_courant).donnee)).objet);
                    885:                    free((*((struct_variable *) (*l_element_courant)
                    886:                            .donnee)).nom);
                    887:                    free((struct_variable *) (*l_element_courant).donnee);
                    888:                }
                    889:                else
                    890:                {
                    891:                    if ((*((struct_variable *) (*l_element_courant).donnee))
                    892:                            .niveau >= 1)
                    893:                    {
                    894:                        liberation(s_etat_processus, (*((struct_variable *)
                    895:                                (*l_element_courant).donnee)).objet);
                    896:                        free((*((struct_variable *) (*l_element_courant)
                    897:                                .donnee)).nom);
                    898:                        free((struct_variable *) (*l_element_courant).donnee);
                    899:                    }
                    900:                }
                    901: 
                    902:                free(l_element_courant);
                    903:                l_element_courant = l_element_suivant;
                    904:            }
                    905: 
                    906:            liberation_arbre_variables(s_etat_processus, (*arbre).noeud[i]);
                    907:        }
                    908:    }
                    909: 
                    910:    free((*arbre).noeud);
                    911:    free(arbre);
                    912: 
                    913:    return;
                    914: }
                    915: 
                    916: /*
                    917: ================================================================================
1.23      bertrand  918:   Procédure de copie de l'arbre des variables
                    919: ================================================================================
                    920:   Entrée :
                    921: --------------------------------------------------------------------------------
                    922:   Sortie :
                    923: --------------------------------------------------------------------------------
                    924:   Effets de bord : néant
                    925: ================================================================================
                    926: */
                    927: 
                    928: struct_arbre_variables *
                    929: copie_arbre_variables(struct_processus *s_etat_processus)
                    930: {
                    931:    // Les définitions sont partagées entre tous les threads et ne sont pas
                    932:    // copiées.
                    933: 
                    934:    return(d_absence_erreur);
                    935: }
                    936: 
                    937: 
                    938: /*
                    939: ================================================================================
                    940:   Procédure d'initialisation de la table de correspondance des variables
                    941: ================================================================================
                    942:   Entrée :
                    943: --------------------------------------------------------------------------------
                    944:   Sortie :
                    945: --------------------------------------------------------------------------------
                    946:   Effets de bord : néant
                    947: ================================================================================
                    948: */
                    949: 
                    950: /*
                    951:  * Caractères autorisés dans les instructions
                    952:  *
                    953:  * 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
                    954:  * 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
                    955:  * _
                    956:  * 1 2 3 4 5 6 7 8 9 0
                    957:  */
                    958: 
                    959: void
                    960: initialisation_variables(struct_processus *s_etat_processus)
                    961: {
                    962:    int             decalage;
                    963:    int             i;
                    964:    int             longueur_tableau;
                    965: 
                    966:    unsigned char   caractere;
                    967: 
                    968:    // Récupération de la longueur d'un unsigned char
                    969: 
                    970:    longueur_tableau = 1;
                    971:    decalage = 0;
                    972:    caractere = 1;
                    973: 
                    974:    while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
                    975:    {
                    976:        decalage++;
                    977:        longueur_tableau *= 2;
                    978:    }
                    979: 
                    980:    if (((*s_etat_processus).pointeurs_caracteres_variables =
                    981:            malloc(longueur_tableau * sizeof(int))) == NULL)
                    982:    {
                    983:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    984:        return;
                    985:    }
                    986: 
                    987:    for(i = 0; i < longueur_tableau; i++)
                    988:    {
                    989:        (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
                    990:    }
                    991: 
                    992:    (*s_etat_processus).nombre_caracteres_variables = 0;
                    993: 
                    994: #define DECLARATION_CARACTERE(c) \
                    995:        do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
                    996:        (*s_etat_processus).nombre_caracteres_variables++; } while(0)
                    997: 
                    998:    DECLARATION_CARACTERE('A');
                    999:    DECLARATION_CARACTERE('B');
                   1000:    DECLARATION_CARACTERE('C');
                   1001:    DECLARATION_CARACTERE('D');
                   1002:    DECLARATION_CARACTERE('E');
                   1003:    DECLARATION_CARACTERE('F');
                   1004:    DECLARATION_CARACTERE('G');
                   1005:    DECLARATION_CARACTERE('H');
                   1006:    DECLARATION_CARACTERE('I');
                   1007:    DECLARATION_CARACTERE('J');
                   1008:    DECLARATION_CARACTERE('K');
                   1009:    DECLARATION_CARACTERE('L');
                   1010:    DECLARATION_CARACTERE('M');
                   1011:    DECLARATION_CARACTERE('N');
                   1012:    DECLARATION_CARACTERE('O');
                   1013:    DECLARATION_CARACTERE('P');
                   1014:    DECLARATION_CARACTERE('Q');
                   1015:    DECLARATION_CARACTERE('R');
                   1016:    DECLARATION_CARACTERE('S');
                   1017:    DECLARATION_CARACTERE('T');
                   1018:    DECLARATION_CARACTERE('U');
                   1019:    DECLARATION_CARACTERE('V');
                   1020:    DECLARATION_CARACTERE('W');
                   1021:    DECLARATION_CARACTERE('X');
                   1022:    DECLARATION_CARACTERE('Y');
                   1023:    DECLARATION_CARACTERE('Z');
                   1024: 
                   1025:    DECLARATION_CARACTERE('a');
                   1026:    DECLARATION_CARACTERE('b');
                   1027:    DECLARATION_CARACTERE('c');
                   1028:    DECLARATION_CARACTERE('d');
                   1029:    DECLARATION_CARACTERE('e');
                   1030:    DECLARATION_CARACTERE('f');
                   1031:    DECLARATION_CARACTERE('g');
                   1032:    DECLARATION_CARACTERE('h');
                   1033:    DECLARATION_CARACTERE('i');
                   1034:    DECLARATION_CARACTERE('j');
                   1035:    DECLARATION_CARACTERE('k');
                   1036:    DECLARATION_CARACTERE('l');
                   1037:    DECLARATION_CARACTERE('m');
                   1038:    DECLARATION_CARACTERE('n');
                   1039:    DECLARATION_CARACTERE('o');
                   1040:    DECLARATION_CARACTERE('p');
                   1041:    DECLARATION_CARACTERE('q');
                   1042:    DECLARATION_CARACTERE('r');
                   1043:    DECLARATION_CARACTERE('s');
                   1044:    DECLARATION_CARACTERE('t');
                   1045:    DECLARATION_CARACTERE('u');
                   1046:    DECLARATION_CARACTERE('v');
                   1047:    DECLARATION_CARACTERE('w');
                   1048:    DECLARATION_CARACTERE('x');
                   1049:    DECLARATION_CARACTERE('y');
                   1050:    DECLARATION_CARACTERE('z');
                   1051: 
                   1052:    DECLARATION_CARACTERE('_');
                   1053: 
                   1054:    DECLARATION_CARACTERE('1');
                   1055:    DECLARATION_CARACTERE('2');
                   1056:    DECLARATION_CARACTERE('3');
                   1057:    DECLARATION_CARACTERE('4');
                   1058:    DECLARATION_CARACTERE('5');
                   1059:    DECLARATION_CARACTERE('6');
                   1060:    DECLARATION_CARACTERE('7');
                   1061:    DECLARATION_CARACTERE('8');
                   1062:    DECLARATION_CARACTERE('9');
                   1063:    DECLARATION_CARACTERE('0');
                   1064: #undef DECLARATION_CARACTERE
                   1065: 
                   1066:    return;
                   1067: }
1.25    ! bertrand 1068: 
1.1       bertrand 1069: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>