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

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
1.27    ! bertrand  579:            // plus ancienne variable est strictement supérieur à 1, il
1.25      bertrand  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;
1.27    ! bertrand  589: 
        !           590:                // S'il existe une variable de niveau 0 et une seconde de
        !           591:                // niveau 1, la variable de niveau 0 (fonction) est masquée
        !           592:                // par celle de niveau 1.
        !           593: 
        !           594:                if (((*(*(*l_variable_courante).feuille).variable).niveau == 0)
        !           595:                        && ((*(*(*(*l_variable_courante).feuille).precedent)
        !           596:                        .variable).niveau == 1))
        !           597:                {
        !           598:                    (*s_etat_processus).pointeur_variable_courante =
        !           599:                            (*(*(*l_variable_courante).feuille).precedent)
        !           600:                            .variable;
        !           601:                    (*s_etat_processus).pointeur_feuille_courante =
        !           602:                            (*l_variable_courante).feuille;
        !           603:                }
        !           604: 
1.25      bertrand  605:                return(d_absence_erreur);
1.12      bertrand  606:            }
                    607:        }
1.1       bertrand  608:    }
                    609: 
1.25      bertrand  610:    return(d_erreur);
1.1       bertrand  611: }
                    612: 
                    613: 
                    614: /*
                    615: ================================================================================
                    616:   Procédure de retrait d'une variable de la base
                    617: ================================================================================
                    618:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
                    619:            les globales) ou strictement globale.
                    620: --------------------------------------------------------------------------------
                    621:   Sortie :
                    622: --------------------------------------------------------------------------------
                    623:   Effets de bord : néant
                    624: ================================================================================
                    625: */
                    626: 
                    627: logical1
                    628: retrait_variable(struct_processus *s_etat_processus,
                    629:        unsigned char *nom_variable, unsigned char type)
                    630: {
                    631:    logical1            erreur;
                    632: 
                    633:    if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
                    634:    {
1.25      bertrand  635:        // Une variable correspondant au nom recherché est accessible.
                    636: 
1.1       bertrand  637:        if (type == 'G')
                    638:        {
1.25      bertrand  639:            if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
                    640:            {
                    641:                // La variable obtenue est une variable locale. il faut
                    642:                // s'assurer qu'il existe une variable de niveau 1 de même
                    643:                // nom sur la feuille.
                    644: 
1.27    ! bertrand  645:                if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
        !           646:                        .precedent).variable).niveau <= 1)
1.1       bertrand  647:                {
1.27    ! bertrand  648:                    (*s_etat_processus).pointeur_feuille_courante =
        !           649:                            (*(*s_etat_processus).pointeur_feuille_courante)
        !           650:                            .precedent;
        !           651:                    (*s_etat_processus).pointeur_variable_courante =
        !           652:                            (*(*s_etat_processus).pointeur_feuille_courante)
        !           653:                            .variable;
        !           654: 
        !           655:                    // Si la variable retournée est de niveau 0, on regarde
        !           656:                    // un peu plus loin si une variable de niveau 1 existe.
        !           657: 
        !           658:                    if (((*(*(*s_etat_processus).pointeur_feuille_courante)
        !           659:                            .variable).niveau == 0) &&
        !           660:                            ((*(*(*(*s_etat_processus)
        !           661:                            .pointeur_feuille_courante).precedent).variable)
        !           662:                            .niveau == 1))
1.1       bertrand  663:                    {
1.27    ! bertrand  664:                        (*s_etat_processus).pointeur_feuille_courante =
        !           665:                                (*(*s_etat_processus).pointeur_feuille_courante)
        !           666:                                .precedent;
        !           667:                        (*s_etat_processus).pointeur_variable_courante =
        !           668:                                (*(*s_etat_processus).pointeur_feuille_courante)
        !           669:                                .variable;
1.1       bertrand  670:                    }
                    671:                }
1.27    ! bertrand  672:                else
        !           673:                {
        !           674:                    // Aucune variable globale (niveau 1) n'existe.
1.1       bertrand  675: 
1.27    ! bertrand  676:                    erreur = d_erreur;
        !           677:                    (*s_etat_processus).erreur_execution =
        !           678:                            d_ex_variable_non_definie;
        !           679:                    return(erreur);
        !           680:                }
1.1       bertrand  681:            }
                    682: 
1.27    ! bertrand  683:            if ((*(*s_etat_processus).pointeur_variable_courante)
1.1       bertrand  684:                    .variable_verrouillee == d_vrai)
                    685:            {
                    686:                erreur = d_erreur;
                    687:                (*s_etat_processus).erreur_execution =
                    688:                        d_ex_variable_verrouillee;
                    689:                return erreur;
                    690:            }
                    691:        }
                    692: 
1.27    ! bertrand  693:        // Suppression de la variable de la liste.
        !           694:        // Deux cas peuvent survenir :
        !           695:        // 1/ les pointeurs sur la variable et la variable suivante
        !           696:        // sont identiques et on supprime la variable ainsi que la feuille
        !           697:        // associée ;
        !           698:        // 2/ ces deux pointeurs sont différents et se contente de retirer
        !           699:        // la structure décrivant la variable.
1.1       bertrand  700: 
                    701:        position_supprimee = (*s_etat_processus).position_variable_courante;
                    702: 
                    703:        liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
                    704:                [position_supprimee].objet);
                    705:        free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
                    706: 
                    707:        (*s_etat_processus).nombre_variables--;
                    708: 
                    709:        for(position_courante = position_supprimee;
                    710:                position_courante < (*s_etat_processus).nombre_variables;
                    711:                position_courante++)
                    712:        {
                    713:            (*s_etat_processus).s_liste_variables[position_courante] =
                    714:                    (*s_etat_processus).s_liste_variables
                    715:                    [position_courante + 1];
                    716:        }
                    717: 
                    718:        erreur = d_absence_erreur;
                    719:    }
                    720:    else
                    721:    {
1.25      bertrand  722:        // Aucune variable n'est accessible depuis le point courant du
                    723:        // programme.
                    724: 
1.1       bertrand  725:        erreur = d_erreur;
                    726:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    727:    }
                    728: 
1.25      bertrand  729:    return(erreur);
1.1       bertrand  730: }
                    731: 
                    732: 
                    733: /*
                    734: ================================================================================
                    735:   Procédure de retrait des variables de niveau strictement supérieur au
                    736:   niveau courant
                    737: ================================================================================
                    738:   Entrée :
                    739: --------------------------------------------------------------------------------
                    740:   Sortie :
                    741: --------------------------------------------------------------------------------
                    742:   Effets de bord : néant
                    743: ================================================================================
                    744: */
                    745: 
                    746: logical1
                    747: retrait_variable_par_niveau(struct_processus *s_etat_processus)
                    748: {
                    749:    unsigned long                   i;
                    750:    unsigned long                   j;
                    751: 
                    752:    struct_variable                 *tampon;
                    753: 
                    754:    for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
                    755:    {
                    756:        if ((*s_etat_processus).s_liste_variables[i].niveau <=
                    757:                (*s_etat_processus).niveau_courant)
                    758:        {
                    759:            (*s_etat_processus).s_liste_variables[j++] =
                    760:                    (*s_etat_processus).s_liste_variables[i];
                    761:        }
                    762:        else
                    763:        {
                    764:            if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
                    765:            {
                    766:                if ((*s_etat_processus).s_liste_variables[i]
                    767:                        .variable_statique.adresse != 0)
                    768:                {
                    769:                    /*
                    770:                     * Gestion des variables statiques
                    771:                     */
                    772: 
                    773:                    if (recherche_variable_statique(s_etat_processus,
                    774:                            (*s_etat_processus).s_liste_variables[i]
                    775:                            .nom, (*s_etat_processus).s_liste_variables
                    776:                            [i].variable_statique, ((*s_etat_processus)
                    777:                            .mode_execution_programme
                    778:                             == 'Y') ? 'P' : 'E') == d_vrai)
                    779:                    {
                    780:                        (*s_etat_processus).s_liste_variables_statiques
                    781:                                [(*s_etat_processus)
                    782:                                .position_variable_statique_courante]
                    783:                                .objet = (*s_etat_processus)
                    784:                                .s_liste_variables[i].objet;
                    785:                    }
                    786:                    else
                    787:                    {
                    788:                        (*s_etat_processus).erreur_systeme =
                    789:                                d_es_variable_introuvable;
                    790:                    }
                    791: 
                    792:                    (*s_etat_processus).s_liste_variables[i].objet = NULL;
                    793:                }
                    794:            }
                    795:            else
                    796:            {
                    797:                if ((*s_etat_processus).s_liste_variables[i]
                    798:                        .variable_statique.pointeur != NULL)
                    799:                {
                    800:                    /*
                    801:                     * Gestion des variables statiques
                    802:                     */
                    803: 
                    804:                    if (recherche_variable_statique(s_etat_processus,
                    805:                            (*s_etat_processus).s_liste_variables[i]
                    806:                            .nom, (*s_etat_processus).s_liste_variables[i]
                    807:                            .variable_statique, ((*s_etat_processus)
                    808:                            .mode_execution_programme
                    809:                             == 'Y') ? 'P' : 'E') == d_vrai)
                    810:                    {
                    811:                        (*s_etat_processus).s_liste_variables_statiques
                    812:                                [(*s_etat_processus)
                    813:                                .position_variable_statique_courante]
                    814:                                .objet = (*s_etat_processus)
                    815:                                .s_liste_variables[i].objet;
                    816:                    }
                    817:                    else
                    818:                    {
                    819:                        (*s_etat_processus).erreur_systeme =
                    820:                                d_es_variable_introuvable;
1.22      bertrand  821:                        return(d_erreur);
1.1       bertrand  822:                    }
                    823: 
                    824:                    (*s_etat_processus).s_liste_variables[i].objet = NULL;
                    825:                }
                    826:            }
                    827: 
                    828:            free((*s_etat_processus).s_liste_variables[i].nom);
                    829:            liberation(s_etat_processus,
                    830:                    (*s_etat_processus).s_liste_variables[i].objet);
                    831:        }
                    832:    }
                    833: 
                    834:    (*s_etat_processus).nombre_variables = j;
                    835: 
                    836:    if ((*s_etat_processus).nombre_variables <
                    837:            ((*s_etat_processus).nombre_variables_allouees / 2))
                    838:    {
                    839:        (*s_etat_processus).nombre_variables_allouees /= 2;
                    840: 
                    841:        if ((tampon = realloc((*s_etat_processus).s_liste_variables,
                    842:                (*s_etat_processus).nombre_variables_allouees *
                    843:                sizeof(struct_variable))) == NULL)
                    844:        {
                    845:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    846:            return(d_erreur);
                    847:        }
                    848: 
                    849:        (*s_etat_processus).s_liste_variables = tampon;
                    850:    }
                    851: 
                    852:    return(d_absence_erreur);
                    853: }
                    854: 
1.23      bertrand  855: 
                    856: /*
                    857: ================================================================================
1.24      bertrand  858:   Procédure de retrait des toutes les variables locales et globales
                    859: ================================================================================
                    860:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
                    861:            de niveau 0)
                    862: --------------------------------------------------------------------------------
                    863:   Sortie :
                    864: --------------------------------------------------------------------------------
                    865:   Effets de bord : néant
                    866: ================================================================================
                    867: */
                    868: 
                    869: void
                    870: liberation_arbre_variables(struct_processus *s_etat_processus,
                    871:        struct_arbre_variables *arbre, logical1 retrait_definitions)
                    872: {
                    873:    int                     i;
                    874: 
                    875:    struct_liste_chainee    *l_element_courant;
                    876:    struct_liste_chainee    *l_element_suivant;
                    877: 
                    878:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                    879:    {
                    880:        if ((*arbre).noeud[i] != NULL)
                    881:        {
                    882:            l_element_courant = (*arbre).l_variables;
                    883: 
                    884:            while(l_element_courant != NULL)
                    885:            {
                    886:                l_element_suivant = (*l_element_courant).suivant;
                    887: 
                    888:                if (retrait_definitions == d_vrai)
                    889:                {
                    890:                    liberation(s_etat_processus, (*((struct_variable *)
                    891:                            (*l_element_courant).donnee)).objet);
                    892:                    free((*((struct_variable *) (*l_element_courant)
                    893:                            .donnee)).nom);
                    894:                    free((struct_variable *) (*l_element_courant).donnee);
                    895:                }
                    896:                else
                    897:                {
                    898:                    if ((*((struct_variable *) (*l_element_courant).donnee))
                    899:                            .niveau >= 1)
                    900:                    {
                    901:                        liberation(s_etat_processus, (*((struct_variable *)
                    902:                                (*l_element_courant).donnee)).objet);
                    903:                        free((*((struct_variable *) (*l_element_courant)
                    904:                                .donnee)).nom);
                    905:                        free((struct_variable *) (*l_element_courant).donnee);
                    906:                    }
                    907:                }
                    908: 
                    909:                free(l_element_courant);
                    910:                l_element_courant = l_element_suivant;
                    911:            }
                    912: 
                    913:            liberation_arbre_variables(s_etat_processus, (*arbre).noeud[i]);
                    914:        }
                    915:    }
                    916: 
                    917:    free((*arbre).noeud);
                    918:    free(arbre);
                    919: 
                    920:    return;
                    921: }
                    922: 
                    923: /*
                    924: ================================================================================
1.23      bertrand  925:   Procédure de copie de l'arbre des variables
                    926: ================================================================================
                    927:   Entrée :
                    928: --------------------------------------------------------------------------------
                    929:   Sortie :
                    930: --------------------------------------------------------------------------------
                    931:   Effets de bord : néant
                    932: ================================================================================
                    933: */
                    934: 
                    935: struct_arbre_variables *
                    936: copie_arbre_variables(struct_processus *s_etat_processus)
                    937: {
                    938:    // Les définitions sont partagées entre tous les threads et ne sont pas
                    939:    // copiées.
                    940: 
                    941:    return(d_absence_erreur);
                    942: }
                    943: 
                    944: 
                    945: /*
                    946: ================================================================================
                    947:   Procédure d'initialisation de la table de correspondance des variables
                    948: ================================================================================
                    949:   Entrée :
                    950: --------------------------------------------------------------------------------
                    951:   Sortie :
                    952: --------------------------------------------------------------------------------
                    953:   Effets de bord : néant
                    954: ================================================================================
                    955: */
                    956: 
                    957: /*
                    958:  * Caractères autorisés dans les instructions
                    959:  *
                    960:  * 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
                    961:  * 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
                    962:  * _
                    963:  * 1 2 3 4 5 6 7 8 9 0
                    964:  */
                    965: 
                    966: void
                    967: initialisation_variables(struct_processus *s_etat_processus)
                    968: {
                    969:    int             decalage;
                    970:    int             i;
                    971:    int             longueur_tableau;
                    972: 
                    973:    unsigned char   caractere;
                    974: 
                    975:    // Récupération de la longueur d'un unsigned char
                    976: 
                    977:    longueur_tableau = 1;
                    978:    decalage = 0;
                    979:    caractere = 1;
                    980: 
                    981:    while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
                    982:    {
                    983:        decalage++;
                    984:        longueur_tableau *= 2;
                    985:    }
                    986: 
                    987:    if (((*s_etat_processus).pointeurs_caracteres_variables =
                    988:            malloc(longueur_tableau * sizeof(int))) == NULL)
                    989:    {
                    990:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    991:        return;
                    992:    }
                    993: 
                    994:    for(i = 0; i < longueur_tableau; i++)
                    995:    {
                    996:        (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
                    997:    }
                    998: 
                    999:    (*s_etat_processus).nombre_caracteres_variables = 0;
                   1000: 
                   1001: #define DECLARATION_CARACTERE(c) \
                   1002:        do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
                   1003:        (*s_etat_processus).nombre_caracteres_variables++; } while(0)
                   1004: 
                   1005:    DECLARATION_CARACTERE('A');
                   1006:    DECLARATION_CARACTERE('B');
                   1007:    DECLARATION_CARACTERE('C');
                   1008:    DECLARATION_CARACTERE('D');
                   1009:    DECLARATION_CARACTERE('E');
                   1010:    DECLARATION_CARACTERE('F');
                   1011:    DECLARATION_CARACTERE('G');
                   1012:    DECLARATION_CARACTERE('H');
                   1013:    DECLARATION_CARACTERE('I');
                   1014:    DECLARATION_CARACTERE('J');
                   1015:    DECLARATION_CARACTERE('K');
                   1016:    DECLARATION_CARACTERE('L');
                   1017:    DECLARATION_CARACTERE('M');
                   1018:    DECLARATION_CARACTERE('N');
                   1019:    DECLARATION_CARACTERE('O');
                   1020:    DECLARATION_CARACTERE('P');
                   1021:    DECLARATION_CARACTERE('Q');
                   1022:    DECLARATION_CARACTERE('R');
                   1023:    DECLARATION_CARACTERE('S');
                   1024:    DECLARATION_CARACTERE('T');
                   1025:    DECLARATION_CARACTERE('U');
                   1026:    DECLARATION_CARACTERE('V');
                   1027:    DECLARATION_CARACTERE('W');
                   1028:    DECLARATION_CARACTERE('X');
                   1029:    DECLARATION_CARACTERE('Y');
                   1030:    DECLARATION_CARACTERE('Z');
                   1031: 
                   1032:    DECLARATION_CARACTERE('a');
                   1033:    DECLARATION_CARACTERE('b');
                   1034:    DECLARATION_CARACTERE('c');
                   1035:    DECLARATION_CARACTERE('d');
                   1036:    DECLARATION_CARACTERE('e');
                   1037:    DECLARATION_CARACTERE('f');
                   1038:    DECLARATION_CARACTERE('g');
                   1039:    DECLARATION_CARACTERE('h');
                   1040:    DECLARATION_CARACTERE('i');
                   1041:    DECLARATION_CARACTERE('j');
                   1042:    DECLARATION_CARACTERE('k');
                   1043:    DECLARATION_CARACTERE('l');
                   1044:    DECLARATION_CARACTERE('m');
                   1045:    DECLARATION_CARACTERE('n');
                   1046:    DECLARATION_CARACTERE('o');
                   1047:    DECLARATION_CARACTERE('p');
                   1048:    DECLARATION_CARACTERE('q');
                   1049:    DECLARATION_CARACTERE('r');
                   1050:    DECLARATION_CARACTERE('s');
                   1051:    DECLARATION_CARACTERE('t');
                   1052:    DECLARATION_CARACTERE('u');
                   1053:    DECLARATION_CARACTERE('v');
                   1054:    DECLARATION_CARACTERE('w');
                   1055:    DECLARATION_CARACTERE('x');
                   1056:    DECLARATION_CARACTERE('y');
                   1057:    DECLARATION_CARACTERE('z');
                   1058: 
                   1059:    DECLARATION_CARACTERE('_');
                   1060: 
                   1061:    DECLARATION_CARACTERE('1');
                   1062:    DECLARATION_CARACTERE('2');
                   1063:    DECLARATION_CARACTERE('3');
                   1064:    DECLARATION_CARACTERE('4');
                   1065:    DECLARATION_CARACTERE('5');
                   1066:    DECLARATION_CARACTERE('6');
                   1067:    DECLARATION_CARACTERE('7');
                   1068:    DECLARATION_CARACTERE('8');
                   1069:    DECLARATION_CARACTERE('9');
                   1070:    DECLARATION_CARACTERE('0');
                   1071: #undef DECLARATION_CARACTERE
                   1072: 
                   1073:    return;
                   1074: }
1.25      bertrand 1075: 
1.1       bertrand 1076: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>