Annotation of rpl/src/gestion_variables_statiques.c, revision 1.37

1.1       bertrand    1: /*
                      2: ================================================================================
1.36      bertrand    3:   RPL/2 (R) version 4.1.11
1.30      bertrand    4:   Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
1.37    ! bertrand   28:   Routine d'ajout d'un bouchon dans la liste des variables statiques
1.1       bertrand   29: ================================================================================
                     30:   Entrée :
                     31: --------------------------------------------------------------------------------
                     32:   Sortie :
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bords : néant
                     35: ================================================================================
                     36: */
                     37: 
1.37    ! bertrand   38: // Routine ajoutant à la liste des variables statiques créées un 'bouchon'
        !            39: // qui est un enregistrement dont la variable est NULL. Cela permet
        !            40: // d'effacer les variables statiques créées dans une expression évaluées car,
        !            41: // l'adresse de ces variables changeant à chaque évaluation, elles ne sont
        !            42: // pas utilisables et constituent une fuite de mémoire
        !            43: 
1.1       bertrand   44: logical1
1.37    ! bertrand   45: ajout_bouchon_variable_statique(struct_processus *s_etat_processus)
1.1       bertrand   46: {
1.37    ! bertrand   47:    struct_liste_variables_statiques    *l_tete_liste;
        !            48: 
        !            49:    l_tete_liste = (*s_etat_processus).l_liste_variables_statiques;
        !            50:    
        !            51:    if (((*s_etat_processus).l_liste_variables_statiques =
        !            52:            malloc(sizeof(struct_liste_variables_statiques))) == NULL)
        !            53:    {
        !            54:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            55:        return(d_erreur);
        !            56:    }
        !            57: 
        !            58:    (*(*s_etat_processus).l_liste_variables_statiques).variable = NULL;
        !            59:    (*(*s_etat_processus).l_liste_variables_statiques).suivant = l_tete_liste;
        !            60:    (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL;
        !            61:    (*l_tete_liste).precedent = (*s_etat_processus).l_liste_variables_statiques;
        !            62: 
        !            63:    return(d_absence_erreur);
        !            64: }
1.1       bertrand   65: 
                     66: 
1.37    ! bertrand   67: /*
        !            68: ================================================================================
        !            69:   Routine de retrait des variables statiques
        !            70: ================================================================================
        !            71:   Entrée :
        !            72: --------------------------------------------------------------------------------
        !            73:   Sortie :
        !            74: --------------------------------------------------------------------------------
        !            75:   Effets de bords : néant
        !            76: ================================================================================
        !            77: */
1.1       bertrand   78: 
1.37    ! bertrand   79: // Cette routine libère toutes les variables statiques jusqu'au prochain
        !            80: // bouchon ou jusqu'à la fin de la liste si aucun bouchon n'est rencontré.
        !            81: 
        !            82: logical1
        !            83: retrait_variables_statiques(struct_processus *s_etat_processus)
        !            84: {
        !            85:    unsigned char                       registre_mode_execution;
1.1       bertrand   86: 
1.37    ! bertrand   87:    registre_mode_execution = (*s_etat_processus).mode_execution_programme;
1.1       bertrand   88: 
1.37    ! bertrand   89:    while((*s_etat_processus).l_liste_variables_statiques != NULL)
        !            90:    {
        !            91:        (*s_etat_processus).mode_execution_programme =
        !            92:                ((*(*(*s_etat_processus).l_liste_variables_statiques)
        !            93:                .variable).origine == 'P') ? 'Y' : 'N';
        !            94: 
        !            95:        if ((*(*s_etat_processus).l_liste_variables_statiques).variable == NULL)
        !            96:        {
        !            97:            // On vient de tomber sur un bouchon...
        !            98:            (*s_etat_processus).l_liste_variables_statiques =
        !            99:                    (*(*s_etat_processus).l_liste_variables_statiques).suivant;
        !           100:            free((*(*s_etat_processus).l_liste_variables_statiques).precedent);
        !           101:            (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL;
        !           102:            break;
        !           103:        }
        !           104: 
        !           105:        if (retrait_variable_statique(s_etat_processus, (*(*(*s_etat_processus)
        !           106:                .l_liste_variables_statiques).variable).nom,
        !           107:                (*(*(*s_etat_processus).l_liste_variables_statiques).variable)
        !           108:                .variable_statique) == d_erreur)
1.1       bertrand  109:        {
1.37    ! bertrand  110:            (*s_etat_processus).mode_execution_programme =
        !           111:                    registre_mode_execution;
1.1       bertrand  112:            return(d_erreur);
                    113:        }
1.37    ! bertrand  114:    }
        !           115: 
        !           116:    (*s_etat_processus).mode_execution_programme = registre_mode_execution;
        !           117:    return(d_absence_erreur);
        !           118: }
        !           119: 
        !           120: 
        !           121: /*
        !           122: ================================================================================
        !           123:   Routine de création d'une nouvelle variable statique
        !           124: ================================================================================
        !           125:   Entrée :
        !           126: --------------------------------------------------------------------------------
        !           127:   Sortie :
        !           128: --------------------------------------------------------------------------------
        !           129:   Effets de bords : néant
        !           130: ================================================================================
        !           131: */
        !           132: 
        !           133: logical1
        !           134: creation_variable_statique(struct_processus *s_etat_processus,
        !           135:        struct_variable_statique *s_variable)
        !           136: {
        !           137:    struct_arbre_variables                  *l_variable_courante;
        !           138: 
        !           139:    struct_liste_variables_statiques        *l_nouvel_element;
1.1       bertrand  140: 
1.37    ! bertrand  141:    unsigned char                           *ptr;
        !           142: 
        !           143:    // Ajout de la variable en tête de la liste des variables statiques
        !           144: 
        !           145:    if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
        !           146:            == NULL)
        !           147:    {
        !           148:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           149:        return(d_erreur);
1.1       bertrand  150:    }
                    151: 
1.37    ! bertrand  152:    if (((*l_nouvel_element).variable = malloc(sizeof(
        !           153:            struct_variable_statique))) == NULL)
        !           154:    {
        !           155:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           156:        return(d_erreur);
        !           157:    }
1.1       bertrand  158: 
1.37    ! bertrand  159:    (*(*l_nouvel_element).variable) = (*s_variable);
        !           160:    (*l_nouvel_element).suivant = (*s_etat_processus)
        !           161:            .l_liste_variables_statiques;
        !           162:    (*(*s_etat_processus).l_liste_variables_statiques).precedent
        !           163:            = l_nouvel_element;
        !           164:    (*l_nouvel_element).precedent = NULL;
        !           165:    (*s_etat_processus).l_liste_variables_statiques = l_nouvel_element;
        !           166: 
        !           167:    // Ajout de la variable à la feuille statique de l'arbre des variables
1.1       bertrand  168: 
1.37    ! bertrand  169:    BUG((*s_etat_processus).s_arbre_variables == NULL,
        !           170:            uprintf("(*s_etat_processus).s_arbre_variables=NULL\n"));
        !           171: 
        !           172:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
        !           173:    ptr = (*s_variable).nom;
        !           174: 
        !           175:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand  176:    {
1.37    ! bertrand  177:        BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
        !           178:                uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
        !           179:                *ptr));
        !           180: 
        !           181:        // La feuille doit préexister car la variable statique est toujours
        !           182:        // créée depuis une variable locale.
        !           183: 
        !           184:        BUG((*l_variable_courante).noeuds[(*s_etat_processus)
        !           185:                .pointeurs_caracteres_variables[*ptr]] == NULL,
        !           186:                uprintf("Variable=\"%s\", (*ptr)='%c', nullified folder\n"));
        !           187: 
        !           188:        l_variable_courante = (*l_variable_courante).noeuds
        !           189:                [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
        !           190:        ptr++;
1.1       bertrand  191:    }
1.37    ! bertrand  192: 
        !           193:    if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
        !           194:            == NULL)
1.1       bertrand  195:    {
1.37    ! bertrand  196:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           197:        return(d_erreur);
1.1       bertrand  198:    }
                    199: 
1.37    ! bertrand  200:    // Dans la feuille statique de l'arbre des variables, on ne balaie
        !           201:    // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
        !           202:    // pour sauvegarder une référence vers la liste des variables statiques
        !           203:    // pour pouvoir purger l'élément en cas de besoin.
        !           204: 
        !           205:    (*l_nouvel_element).suivant = (*l_variable_courante).feuille_statique;
        !           206:    (*l_nouvel_element).precedent = NULL;
        !           207:    (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
        !           208: 
        !           209:    (*l_nouvel_element).reference =
        !           210:            (*s_etat_processus).l_liste_variables_statiques;
        !           211:    (*l_nouvel_element).variable = (*(*s_etat_processus)
        !           212:            .l_liste_variables_statiques).variable;
        !           213:    (*l_variable_courante).feuille_statique = l_nouvel_element;
        !           214:    return(d_absence_erreur);
1.1       bertrand  215: }
                    216: 
                    217: 
                    218: /*
                    219: ================================================================================
                    220:   Procédure de retrait d'une variable statique de la base
                    221: ================================================================================
                    222:   Entrée :
                    223: --------------------------------------------------------------------------------
                    224:   Sortie :
                    225: --------------------------------------------------------------------------------
                    226:   Effets de bord : néant
                    227: ================================================================================
                    228: */
                    229: 
                    230: logical1
                    231: retrait_variable_statique(struct_processus *s_etat_processus,
                    232:        unsigned char *nom_variable, union_position_variable position)
                    233: {
1.37    ! bertrand  234:    struct_liste_variables_statiques        *l_element_a_supprimer;
        !           235:    struct_liste_variables_statiques        *l_element_liste_a_supprimer;
        !           236: 
        !           237:    logical1                                erreur;
        !           238: 
        !           239:    if ((l_element_a_supprimer = recherche_variable_statique(s_etat_processus,
        !           240:            nom_variable, position, ((*s_etat_processus)
        !           241:            .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
        !           242:    {
        !           243:        // (*s_etat_processus).pointeur_variable_statique_courante
        !           244:        // pointe sur la variable à éliminer. Cette variable est celle qui
        !           245:        // est présente dans l'une des feuilles statiques de l'arbre des
        !           246:        // variables.
1.1       bertrand  247: 
1.37    ! bertrand  248:        l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1       bertrand  249: 
1.37    ! bertrand  250:        // Suppression de la liste des variables statiques
1.1       bertrand  251: 
1.37    ! bertrand  252:        if ((*l_element_liste_a_supprimer).precedent != NULL)
        !           253:        {
        !           254:            (*(*l_element_liste_a_supprimer).precedent).suivant =
        !           255:                    (*l_element_liste_a_supprimer).suivant;
        !           256:        }
        !           257:        else
1.1       bertrand  258:        {
1.37    ! bertrand  259:            (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
        !           260:        }
1.1       bertrand  261: 
1.37    ! bertrand  262:        if ((*l_element_liste_a_supprimer).suivant != NULL)
        !           263:        {
        !           264:            (*(*l_element_liste_a_supprimer).suivant).precedent =
        !           265:                    (*l_element_liste_a_supprimer).precedent;
        !           266:        }
        !           267:        else
        !           268:        {
        !           269:            (*(*l_element_liste_a_supprimer).precedent).suivant = NULL;
1.1       bertrand  270:        }
                    271: 
1.37    ! bertrand  272:        free(l_element_liste_a_supprimer);
1.1       bertrand  273: 
1.37    ! bertrand  274:        // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
        !           275:        // pas car la liste est simplement chaînée.
1.1       bertrand  276: 
1.37    ! bertrand  277:        if ((*l_element_a_supprimer).precedent != NULL)
        !           278:        {
        !           279:            (*(*l_element_a_supprimer).precedent).suivant =
        !           280:                    (*l_element_a_supprimer).suivant;
        !           281:        }
        !           282:        else
        !           283:        {
        !           284:            (*(*l_element_a_supprimer).suivant).precedent = NULL;
        !           285:        }
1.1       bertrand  286: 
1.37    ! bertrand  287:        if ((*l_element_a_supprimer).suivant != NULL)
        !           288:        {
        !           289:            (*(*l_element_a_supprimer).suivant).precedent =
        !           290:                    (*l_element_a_supprimer).precedent;
        !           291:        }
        !           292:        else
1.1       bertrand  293:        {
1.37    ! bertrand  294:            (*(*l_element_a_supprimer).precedent).suivant = NULL;
1.1       bertrand  295:        }
                    296: 
1.37    ! bertrand  297:        liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
        !           298:                .objet);
        !           299:        free((*(*l_element_a_supprimer).variable).nom);
        !           300:        free((*l_element_a_supprimer).variable);
        !           301:        free(l_element_a_supprimer);
        !           302: 
1.1       bertrand  303:        erreur = d_absence_erreur;
                    304:    }
                    305:    else
                    306:    {
                    307:        erreur = d_erreur;
                    308:        (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                    309:    }
                    310: 
                    311:    return erreur;
                    312: }
                    313: 
                    314: 
                    315: /*
                    316: ================================================================================
                    317:   Procédure de recherche d'une variable statique par son nom dans la base
                    318: ================================================================================
                    319:   Entrée :
                    320: --------------------------------------------------------------------------------
                    321:   Sortie :
                    322: --------------------------------------------------------------------------------
                    323:   Effets de bord : néant
                    324: ================================================================================
                    325: */
                    326: 
1.37    ! bertrand  327: struct_liste_variables_statiques *
1.1       bertrand  328: recherche_variable_statique(struct_processus *s_etat_processus,
                    329:        unsigned char *nom_variable, union_position_variable position,
                    330:        unsigned char origine)
                    331: {
1.37    ! bertrand  332:    int                                 pointeur;
1.1       bertrand  333: 
1.37    ! bertrand  334:    struct_arbre_variables              *l_variable_courante;
        !           335:    struct_liste_variables_statiques    *l_element_courant;
1.1       bertrand  336: 
1.37    ! bertrand  337:    unsigned char                       *ptr;
1.1       bertrand  338: 
1.37    ! bertrand  339:    l_variable_courante = (*s_etat_processus).s_arbre_variables;
        !           340:    ptr = nom_variable;
1.1       bertrand  341: 
1.37    ! bertrand  342:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand  343:    {
1.37    ! bertrand  344:        pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1.1       bertrand  345: 
1.37    ! bertrand  346:        if (pointeur < 0)
1.1       bertrand  347:        {
1.37    ! bertrand  348:            // Caractère hors de l'alphabet des variables
1.1       bertrand  349: 
1.37    ! bertrand  350:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
        !           351:            return(NULL);
1.1       bertrand  352:        }
1.37    ! bertrand  353: 
        !           354:        if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1       bertrand  355:        {
1.37    ! bertrand  356:            // Le chemin de la variable candidate n'existe pas.
        !           357:            (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
        !           358:            return(NULL);
1.1       bertrand  359:        }
                    360: 
1.37    ! bertrand  361:        l_variable_courante = (*l_variable_courante).noeuds[pointeur];
        !           362:        ptr++;
1.1       bertrand  363:    }
1.37    ! bertrand  364: 
        !           365:    if ((*l_variable_courante).feuille_statique != NULL)
1.1       bertrand  366:    {
1.37    ! bertrand  367:        // Il existe au moins une variable statique du nom requis.
1.1       bertrand  368: 
1.37    ! bertrand  369:        l_element_courant = (*l_variable_courante).feuille_statique;
1.1       bertrand  370: 
1.37    ! bertrand  371:        while(l_element_courant != NULL)
1.1       bertrand  372:        {
1.37    ! bertrand  373:            if ((*(*l_element_courant).variable).origine == 'P')
1.1       bertrand  374:            {
1.37    ! bertrand  375:                if (((*(*l_element_courant).variable).variable_statique.adresse
        !           376:                        == position.adresse) &&
        !           377:                        ((*(*l_element_courant).variable).origine == origine))
1.1       bertrand  378:                {
1.37    ! bertrand  379:                    (*s_etat_processus).pointeur_variable_statique_courante
        !           380:                            =   (*l_element_courant).variable;
        !           381:                    return(l_element_courant);
1.1       bertrand  382:                }
                    383:            }
1.37    ! bertrand  384:            else
1.1       bertrand  385:            {
1.37    ! bertrand  386:                if (((*(*l_element_courant).variable).variable_statique.pointeur
        !           387:                        == position.pointeur) &&
        !           388:                        ((*(*l_element_courant).variable).origine == origine))
1.1       bertrand  389:                {
1.37    ! bertrand  390:                    (*s_etat_processus).pointeur_variable_statique_courante
        !           391:                            =   (*l_element_courant).variable;
        !           392:                    return(l_element_courant);
1.1       bertrand  393:                }
                    394:            }
                    395:        }
                    396:    }
                    397: 
1.37    ! bertrand  398:    (*s_etat_processus).pointeur_variable_statique_courante = NULL;
        !           399:    return(NULL);
1.1       bertrand  400: }
                    401: 
                    402: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>