Annotation of rpl/src/gestion_pile.c, revision 1.1

1.1     ! bertrand    1: /*
        !             2: ================================================================================
        !             3:   RPL/2 (R) version 4.0.9
        !             4:   Copyright (C) 1989-2010 Dr. BERTRAND Joël
        !             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: 
        !            23: #include "rpl.conv.h"
        !            24: 
        !            25: 
        !            26: /*
        !            27: ================================================================================
        !            28:   Procédure d'estimation de la longueur du tampon
        !            29: ================================================================================
        !            30:   Entrée :
        !            31: --------------------------------------------------------------------------------
        !            32:   Sortie :
        !            33: --------------------------------------------------------------------------------
        !            34:   Effets de bord : néant
        !            35: ================================================================================
        !            36: */
        !            37: 
        !            38: static inline void
        !            39: estimation_taille_pile(struct_processus *s_etat_processus)
        !            40: {
        !            41:    /*
        !            42:     * Cette fonction permet d'estimer un volant de structures de maillons
        !            43:     * de liste chaînée pour le programme courant et évite un certain nombre
        !            44:     * d'allocations de mémoire lors des manipulations de la pile. Cette taille
        !            45:     * est estimée au travers d'une chaîne de Markov.
        !            46:     */
        !            47: 
        !            48:    (*s_etat_processus).estimation_taille_pile_tampon =
        !            49:            ((*s_etat_processus).estimation_taille_pile_tampon *
        !            50:            ((double) 0.9)) + ((*s_etat_processus)
        !            51:            .hauteur_pile_operationnelle * ((double) 0.1));
        !            52:    return;
        !            53: }
        !            54: 
        !            55: 
        !            56: /*
        !            57: ================================================================================
        !            58:   Procédure d'empilement d'un nouvel élément
        !            59: ================================================================================
        !            60:   Entrée :
        !            61: --------------------------------------------------------------------------------
        !            62:   Sortie :
        !            63: --------------------------------------------------------------------------------
        !            64:   Effets de bord : néant
        !            65: ================================================================================
        !            66: */
        !            67: 
        !            68: logical1
        !            69: empilement(struct_processus *s_etat_processus,
        !            70:        struct_liste_chainee **l_base_pile, struct_objet *s_objet)
        !            71: {
        !            72:    struct_liste_chainee        *l_ancienne_base_liste;
        !            73:    struct_liste_chainee        *l_nouvelle_base_liste;
        !            74: 
        !            75:    logical1                    erreur;
        !            76: 
        !            77:    l_ancienne_base_liste = *l_base_pile;
        !            78: 
        !            79:    if ((*s_etat_processus).pile_tampon == NULL)
        !            80:    {
        !            81:        // Tampon vide, on alloue un élément.
        !            82: 
        !            83:        if ((l_nouvelle_base_liste = malloc(sizeof(struct_liste_chainee)))
        !            84:                == NULL)
        !            85:        {
        !            86:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            87:            return(d_erreur);
        !            88:        }
        !            89:    }
        !            90:    else
        !            91:    {
        !            92:        // Tampon utilisable, on retire un élément du tampon.
        !            93: 
        !            94:        l_nouvelle_base_liste = (*s_etat_processus).pile_tampon;
        !            95:        (*s_etat_processus).pile_tampon = (*l_nouvelle_base_liste).suivant;
        !            96:        (*s_etat_processus).taille_pile_tampon--;
        !            97:    }
        !            98: 
        !            99:    *l_base_pile = l_nouvelle_base_liste;
        !           100:    (**l_base_pile).donnee = s_objet;
        !           101:    (**l_base_pile).suivant = l_ancienne_base_liste;
        !           102: 
        !           103:    erreur = d_absence_erreur;
        !           104: 
        !           105: /*
        !           106: -- Ne considère que la pile opérationnelle -------------------------------------
        !           107: */
        !           108: 
        !           109:    if ((*s_etat_processus).l_base_pile == *l_base_pile)
        !           110:    {
        !           111:        (*s_etat_processus).hauteur_pile_operationnelle++;
        !           112:        estimation_taille_pile(s_etat_processus);
        !           113: 
        !           114:        if ((*s_etat_processus).debug == d_vrai)
        !           115:            if (((*s_etat_processus).type_debug &
        !           116:                    d_debug_pile_utilisateur) != 0)
        !           117:        {
        !           118:            if ((*s_etat_processus).langue == 'F')
        !           119:            {
        !           120:                printf("[%d] Empilement de type %d "
        !           121:                        "(profondeur %lu)\n", (int) getpid(),
        !           122:                        (*s_objet).type,
        !           123:                        (*s_etat_processus).hauteur_pile_operationnelle);
        !           124:            }
        !           125:            else
        !           126:            {
        !           127:                printf("[%d] Pushing a type %d object "
        !           128:                        "(depth %lu)\n", (int) getpid(), (*s_objet).type,
        !           129:                        (*s_etat_processus).hauteur_pile_operationnelle);
        !           130:            }
        !           131: 
        !           132:            fflush(stdout);
        !           133:        }
        !           134:    }
        !           135: 
        !           136:    return erreur;
        !           137: }
        !           138: 
        !           139: 
        !           140: /*
        !           141: ================================================================================
        !           142:   Procédure de dépilement d'un élément. L'emplacement est libéré dans la pile.
        !           143: ================================================================================
        !           144:   Entrée :
        !           145: --------------------------------------------------------------------------------
        !           146:   Sortie :
        !           147: --------------------------------------------------------------------------------
        !           148:   Effets de bord : néant
        !           149: ================================================================================
        !           150: */
        !           151: 
        !           152: logical1
        !           153: depilement(struct_processus *s_etat_processus,
        !           154:        struct_liste_chainee **l_base_pile, struct_objet **s_objet)
        !           155: {
        !           156:    struct_liste_chainee        *l_ancienne_base_liste;
        !           157:    struct_liste_chainee        *l_nouvelle_base_liste;
        !           158: 
        !           159:    logical1                    erreur;
        !           160: 
        !           161:    if (*l_base_pile == NULL)
        !           162:    {
        !           163:        (*s_etat_processus).erreur_execution = d_ex_pile_vide;
        !           164:        erreur = d_erreur;
        !           165:    }
        !           166:    else
        !           167:    {
        !           168: 
        !           169: /*
        !           170: -- Ne considère que la pile opérationnelle -------------------------------------
        !           171: */
        !           172: 
        !           173:        l_ancienne_base_liste = *l_base_pile;
        !           174:        *s_objet = (*l_ancienne_base_liste).donnee;
        !           175: 
        !           176:        if ((*s_etat_processus).l_base_pile == *l_base_pile)
        !           177:        {
        !           178:            if ((*s_etat_processus).debug == d_vrai)
        !           179:                if (((*s_etat_processus).type_debug &
        !           180:                        d_debug_pile_utilisateur) != 0)
        !           181:            {
        !           182:                if ((*s_etat_processus).langue == 'F')
        !           183:                {
        !           184:                    printf("[%d] Dépilement de type %d "
        !           185:                            "(profondeur %lu)\n", (int) getpid(),
        !           186:                            (*(*s_objet)).type,
        !           187:                            (*s_etat_processus).hauteur_pile_operationnelle);
        !           188:                }
        !           189:                else
        !           190:                {
        !           191:                    printf("[%d] Pulling a type %d object "
        !           192:                            "(depth %lu)\n", (int) getpid(), (*(*s_objet)).type,
        !           193:                            (*s_etat_processus).hauteur_pile_operationnelle);
        !           194:                }
        !           195: 
        !           196:                fflush(stdout);
        !           197:            }
        !           198: 
        !           199:            (*s_etat_processus).hauteur_pile_operationnelle--;
        !           200:            estimation_taille_pile(s_etat_processus);
        !           201:        }
        !           202: 
        !           203:        l_nouvelle_base_liste = (*l_ancienne_base_liste).suivant;
        !           204: 
        !           205:        *l_base_pile = l_nouvelle_base_liste;
        !           206:        erreur = d_absence_erreur;
        !           207: 
        !           208:        if ((*s_etat_processus).taille_pile_tampon <= (10 * ((*s_etat_processus)
        !           209:                .estimation_taille_pile_tampon + 1)))
        !           210:        {
        !           211:            // Enregistrement de la structure pour usage ultérieur.
        !           212: 
        !           213:            (*l_ancienne_base_liste).donnee = NULL;
        !           214:            (*l_ancienne_base_liste).suivant = (*s_etat_processus).pile_tampon;
        !           215:            (*s_etat_processus).pile_tampon = l_ancienne_base_liste;
        !           216:            (*s_etat_processus).taille_pile_tampon++;
        !           217:        }
        !           218:        else
        !           219:        {
        !           220:            // Libération car le tampon est plein.
        !           221: 
        !           222:            free(l_ancienne_base_liste);
        !           223:        }
        !           224:    }
        !           225: 
        !           226:    return erreur;
        !           227: }
        !           228: 
        !           229: 
        !           230: /*
        !           231: ================================================================================
        !           232:   Procédures affichant la pile opérationnelle
        !           233: ================================================================================
        !           234:   Entrée :
        !           235: --------------------------------------------------------------------------------
        !           236:   Sortie :
        !           237: --------------------------------------------------------------------------------
        !           238:   Effets de bord : néant
        !           239: ================================================================================
        !           240: */
        !           241: 
        !           242: void
        !           243: affichage_pile(struct_processus *s_etat_processus, struct_liste_chainee
        !           244:        *l_element_courant, unsigned long niveau_courant)
        !           245: {
        !           246:    ecriture_pile(s_etat_processus, stdout, l_element_courant, niveau_courant);
        !           247:    return;
        !           248: }
        !           249: 
        !           250: void
        !           251: ecriture_pile(struct_processus *s_etat_processus, file *flux,
        !           252:        struct_liste_chainee *l_element_courant, unsigned long niveau_courant)
        !           253: {
        !           254:    unsigned char               *chaine;
        !           255:    unsigned char               *registre;
        !           256:    unsigned char               tampon[32 + 1];
        !           257: 
        !           258:    if (l_element_courant != NULL)
        !           259:    {
        !           260:        if (setjmp(contexte) == 0)
        !           261:        {
        !           262:            (*s_etat_processus).var_volatile_recursivite = -1;
        !           263:            ecriture_pile(s_etat_processus, flux,
        !           264:                    (*l_element_courant).suivant, niveau_courant + 1);
        !           265: 
        !           266:            if ((*s_etat_processus).var_volatile_recursivite > 0)
        !           267:            {
        !           268:                (*s_etat_processus).var_volatile_recursivite--;
        !           269: 
        !           270:                if ((*s_etat_processus).var_volatile_recursivite == 0)
        !           271:                {
        !           272:                    if (fprintf(flux, "%lu: ...\n", niveau_courant) < 0)
        !           273:                    {
        !           274:                        (*s_etat_processus).erreur_systeme =
        !           275:                                d_es_erreur_fichier;
        !           276:                        return;
        !           277:                    }
        !           278: 
        !           279:                    while(l_element_courant != NULL)
        !           280:                    {
        !           281:                        l_element_courant = (*l_element_courant).suivant;
        !           282:                    }
        !           283:                }
        !           284: 
        !           285:                return;
        !           286:            }
        !           287: 
        !           288:            (*s_etat_processus).var_volatile_recursivite = 0;
        !           289:        }
        !           290:        else
        !           291:        {
        !           292:            // Libération de n appels de la pile système qui permet de
        !           293:            // terminer la récursion sans autre dépassement de pile.
        !           294: 
        !           295:            (*s_etat_processus).var_volatile_recursivite = 64;
        !           296:            return;
        !           297:        }
        !           298: 
        !           299:        sprintf(tampon, "%lu: ", niveau_courant);
        !           300: 
        !           301:        if ((chaine = formateur(s_etat_processus, strlen(tampon),
        !           302:                (*l_element_courant).donnee)) == NULL)
        !           303:        {
        !           304:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           305:            return;
        !           306:        }
        !           307: 
        !           308:        if ((*(*l_element_courant).donnee).type == CHN)
        !           309:        {
        !           310:            registre = chaine;
        !           311: 
        !           312:            if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) *
        !           313:                    sizeof(unsigned char))) == NULL)
        !           314:            {
        !           315:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           316:                return;
        !           317:            }
        !           318: 
        !           319:            sprintf(chaine, "\"%s\"", registre);
        !           320:            free(registre);
        !           321:        }
        !           322: 
        !           323:        if (fprintf(flux, "%lu: %s\n", niveau_courant, chaine) < 0)
        !           324:        {
        !           325:            (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
        !           326:            return;
        !           327:        }
        !           328: 
        !           329:        free(chaine);
        !           330:    }
        !           331: 
        !           332:    return;
        !           333: }
        !           334: 
        !           335: 
        !           336: /*
        !           337: ================================================================================
        !           338:   Procédure imprimant la pile opérationnelle
        !           339: ================================================================================
        !           340:   Entrée : méthode 'C' = compacte, 'E' = étendue
        !           341: --------------------------------------------------------------------------------
        !           342:   Sortie :
        !           343: --------------------------------------------------------------------------------
        !           344:   Effets de bord : néant
        !           345: ================================================================================
        !           346: */
        !           347: 
        !           348: void
        !           349: impression_pile(struct_processus *s_etat_processus,
        !           350:        struct_liste_chainee *l_element_courant, unsigned char methode,
        !           351:        unsigned long niveau_courant)
        !           352: {
        !           353:    struct_objet                s_objet;
        !           354: 
        !           355:    unsigned char               *chaine;
        !           356:    unsigned char               *registre;
        !           357:    unsigned char               tampon[32 + 1];
        !           358: 
        !           359:    if (l_element_courant != NULL)
        !           360:    {
        !           361:        if (setjmp(contexte) == 0)
        !           362:        {
        !           363:            (*s_etat_processus).var_volatile_recursivite = -1;
        !           364:            impression_pile(s_etat_processus, (*l_element_courant).suivant,
        !           365:                    methode, niveau_courant + 1);
        !           366: 
        !           367:            if ((*s_etat_processus).var_volatile_recursivite > 0)
        !           368:            {
        !           369:                (*s_etat_processus).var_volatile_recursivite--;
        !           370: 
        !           371:                if ((*s_etat_processus).var_volatile_recursivite == 0)
        !           372:                {
        !           373:                    while(l_element_courant != NULL)
        !           374:                    {
        !           375:                        l_element_courant = (*l_element_courant).suivant;
        !           376:                    }
        !           377:                }
        !           378: 
        !           379:                return;
        !           380:            }
        !           381: 
        !           382:            (*s_etat_processus).var_volatile_recursivite = 0;
        !           383:        }
        !           384:        else
        !           385:        {
        !           386:            (*s_etat_processus).var_volatile_recursivite = 16;
        !           387:            return;
        !           388:        }
        !           389: 
        !           390:        if (methode == 'C')
        !           391:        {
        !           392:            s_objet.type = CHN;
        !           393:            sprintf(tampon, "%lu: ", niveau_courant);
        !           394: 
        !           395:            if ((chaine = formateur(s_etat_processus, strlen(tampon),
        !           396:                    (*l_element_courant).donnee)) == NULL)
        !           397:            {
        !           398:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           399:                return;
        !           400:            }
        !           401: 
        !           402:            if ((*(*l_element_courant).donnee).type == CHN)
        !           403:            {
        !           404:                registre = chaine;
        !           405: 
        !           406:                if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) *
        !           407:                        sizeof(unsigned char))) == NULL)
        !           408:                {
        !           409:                    (*s_etat_processus).erreur_systeme =
        !           410:                            d_es_allocation_memoire;
        !           411:                    return;
        !           412:                }
        !           413: 
        !           414:                sprintf(chaine, "\"%s\"", registre);
        !           415:                free(registre);
        !           416:            }
        !           417: 
        !           418:            if ((s_objet.objet = malloc((strlen(chaine) + 64) *
        !           419:                    sizeof(unsigned char))) == NULL)
        !           420:            {
        !           421:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           422:                return;
        !           423:            }
        !           424: 
        !           425:            sprintf((unsigned char *) s_objet.objet,
        !           426:                    "\n\\noindent\\begin{verbatim}\n%lu: %s\n\\end{verbatim}",
        !           427:                    niveau_courant, chaine);
        !           428:            free(chaine);
        !           429: 
        !           430:            formateur_tex(s_etat_processus, &s_objet, 'V');
        !           431:            free(s_objet.objet);
        !           432:        }
        !           433:        else
        !           434:        {
        !           435:            formateur_tex(s_etat_processus, (*l_element_courant).donnee, 'N');
        !           436:        }
        !           437:    }
        !           438: 
        !           439:    return;
        !           440: }
        !           441: 
        !           442: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>