File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.11: download - view: text, annotated - select for diffs - revision graph
Wed Jun 9 12:19:13 2010 UTC (13 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction de fuites de mémoire, suite et pas fin...

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.16
    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: static pthread_mutex_t          mutex = PTHREAD_MUTEX_INITIALIZER;
   26: 
   27: 
   28: /*
   29: ================================================================================
   30:   Procédure de chargement d'une bibliothèque dynamique
   31: ================================================================================
   32:   Entrée :
   33: --------------------------------------------------------------------------------
   34:   Sortie :
   35: --------------------------------------------------------------------------------
   36:   Effets de bord : néant
   37: ================================================================================
   38: */
   39: 
   40: void *
   41: chargement_bibliotheque(struct_processus *s_etat_processus,
   42:         unsigned char *bibliotheque)
   43: {
   44:     char                    **(*fonction)(unsigned long *, const char *);
   45:     char                    *message;
   46: 
   47:     long                    i;
   48:     long                    nombre_symboles;
   49: 
   50:     struct_rpl_arguments    rpl_arguments;
   51: 
   52:     struct_liste_chainee    *l_element_courant;
   53:     struct_liste_chainee    *l_nouvel_element;
   54: 
   55:     unsigned char           **tableau;
   56:     unsigned char           *tampon;
   57: 
   58:     void                    *descripteur_bibliotheque;
   59:     void                    (*onloading)(struct_rpl_arguments *);
   60: 
   61:     /*
   62:      * On vérifie que la bibliothèque n'est pas déjà chargée.
   63:      */
   64: 
   65:     l_element_courant = (*s_etat_processus).s_bibliotheques;
   66: 
   67:     while(l_element_courant != NULL)
   68:     {
   69:         if (strcmp((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom,
   70:                 bibliotheque) == 0)
   71:         {
   72:             (*s_etat_processus).erreur_execution = d_ex_bibliotheque_chargee;
   73:             return(NULL);
   74:         }
   75: 
   76:         l_element_courant = (*l_element_courant).suivant;
   77:     }
   78: 
   79:     /*
   80:      * Ouverture de la bibliothèque
   81:      */
   82: 
   83:     if ((descripteur_bibliotheque = dlopen(bibliotheque,
   84:             RTLD_NOW | RTLD_LOCAL)) == NULL)
   85:     {
   86:         if (pthread_mutex_lock(&mutex) != 0)
   87:         {
   88:             (*s_etat_processus).erreur_systeme = d_es_processus;
   89:             return(NULL);
   90:         }
   91: 
   92:         printf("%s\n", dlerror());
   93: 
   94:         if (pthread_mutex_unlock(&mutex) != 0)
   95:         {
   96:             (*s_etat_processus).erreur_systeme = d_es_processus;
   97:             return(NULL);
   98:         }
   99: 
  100:         (*s_etat_processus).erreur_execution = d_ex_erreur_bibliotheque;
  101:         return(NULL);
  102:     }
  103: 
  104:     if (pthread_mutex_lock(&mutex) != 0)
  105:     {
  106:         (*s_etat_processus).erreur_systeme = d_es_processus;
  107:         return(NULL);
  108:     }
  109: 
  110:     dlerror();
  111:     onloading = dlsym(descripteur_bibliotheque, "__runOnLoading");
  112: 
  113:     if (((message = dlerror()) == NULL) && (onloading != NULL))
  114:     {
  115:         if (pthread_mutex_unlock(&mutex) != 0)
  116:         {
  117:             (*s_etat_processus).erreur_systeme = d_es_processus;
  118:             return(NULL);
  119:         }
  120: 
  121:         rpl_arguments.l_base_pile = (*s_etat_processus).l_base_pile;
  122:         rpl_arguments.l_base_pile_last = (*s_etat_processus).l_base_pile_last;
  123: 
  124:         for(i = 0; i < 8; i++)
  125:         {
  126:             rpl_arguments.drapeaux_etat[i] =
  127:                     (*s_etat_processus).drapeaux_etat[i];
  128:         }
  129: 
  130:         rpl_arguments.message_erreur = NULL;
  131:         rpl_arguments.type_erreur = 'E';
  132:         rpl_arguments.erreur = 0;
  133:         rpl_arguments.aide = ((*s_etat_processus).affichage_arguments
  134:                 == 'N') ? d_faux : d_vrai;
  135:         rpl_arguments.affichage_arguments = (*s_etat_processus)
  136:                 .affichage_arguments;
  137:         rpl_arguments.test_instruction = (*s_etat_processus).test_instruction;
  138:         rpl_arguments.constante_symbolique = (*s_etat_processus)
  139:                 .constante_symbolique;
  140:         rpl_arguments.instruction_valide = 'N';
  141:         rpl_arguments.s_etat_processus = s_etat_processus;
  142: 
  143:         (*s_etat_processus).erreur_execution = d_ex;
  144: 
  145:         if ((*s_etat_processus).profilage == d_vrai)
  146:         {
  147:             if ((tampon = malloc((strlen(bibliotheque) + 14) *
  148:                     sizeof(unsigned char))) == NULL)
  149:             {
  150:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  151:                 return(NULL);
  152:             }
  153: 
  154:             sprintf(tampon, "%s$runOnLoading", bibliotheque);
  155:             profilage(s_etat_processus, tampon);
  156:             free(tampon);
  157: 
  158:             if ((*s_etat_processus).erreur_systeme != d_es)
  159:             {
  160:                 return(NULL);
  161:             }
  162:         }
  163: 
  164: #       ifndef SEMAPHORES_NOMMES
  165:         if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
  166:         {
  167:             (*s_etat_processus).erreur_systeme = d_es_processus;
  168:             return(NULL);
  169:         }
  170: #       else
  171:         if (sem_post((*s_etat_processus).semaphore_fork) != 0)
  172:         {
  173:             (*s_etat_processus).erreur_systeme = d_es_processus;
  174:             return(NULL);
  175:         }
  176: #       endif
  177: 
  178:         (*onloading)(&rpl_arguments);
  179: 
  180: #       ifndef SEMAPHORES_NOMMES
  181:         while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
  182:         {
  183:             if (errno != EINTR)
  184:             {
  185:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  186:                 return(NULL);
  187:             }
  188:         }
  189: #       else
  190:         while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
  191:         {
  192:             if (errno != EINTR)
  193:             {
  194:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  195:                 return(NULL);
  196:             }
  197:         }
  198: #       endif
  199: 
  200:         if ((*s_etat_processus).profilage == d_vrai)
  201:         {
  202:             profilage(s_etat_processus, NULL);
  203:         }
  204: 
  205:         (*s_etat_processus).nombre_arguments = rpl_arguments.nombre_arguments;
  206:         (*s_etat_processus).constante_symbolique = rpl_arguments
  207:                 .constante_symbolique;
  208:         (*s_etat_processus).instruction_valide = rpl_arguments
  209:                 .instruction_valide;
  210: 
  211:         if ((*s_etat_processus).test_instruction == 'Y')
  212:         {
  213:             if ((*s_etat_processus).nombre_arguments == 0)
  214:             {
  215:                 (*s_etat_processus).nombre_arguments = -1;
  216:             }
  217:         }
  218: 
  219:         if (rpl_arguments.erreur != 0)
  220:         {
  221:             if (((*s_etat_processus).arret_si_exception == d_vrai) ||
  222:                     (rpl_arguments.type_erreur == 'S'))
  223:             {
  224:                 if (test_cfsf(s_etat_processus, 51) == d_faux)
  225:                 {
  226:                     printf("%s", ds_beep);
  227:                 }
  228: 
  229:                 if (rpl_arguments.type_erreur == 'S')
  230:                 {
  231:                     (*s_etat_processus).derniere_erreur_execution = -1;
  232: 
  233:                     if ((*s_etat_processus).langue == 'F')
  234:                     {
  235:                         printf("+++Système : Fonction dynamique %s "
  236:                                 "(ligne %lld)\n",
  237:                                 "onLoading", rpl_arguments.erreur);
  238:                     }
  239:                     else
  240:                     {
  241:                         printf("+++System : %s dynamic function (line %lld)\n",
  242:                                 "onLoading", rpl_arguments.erreur);
  243:                     }
  244:                 }
  245:                 else
  246:                 {
  247:                     (*s_etat_processus).derniere_erreur_systeme = -1;
  248: 
  249:                     if ((*s_etat_processus).langue == 'F')
  250:                     {
  251:                         printf("+++Erreur : Fonction dynamique %s "
  252:                                 "(ligne %lld)\n",
  253:                                 "onLoading" , rpl_arguments.erreur);
  254:                     }
  255:                     else
  256:                     {
  257:                         printf("+++Error : %s dynamic function (line %lld)\n",
  258:                                 "onLoading", rpl_arguments.erreur);
  259:                     }
  260:                 }
  261: 
  262:                 if (rpl_arguments.message_erreur != NULL)
  263:                 {
  264:                     printf("%s\n", rpl_arguments.message_erreur);
  265:                 }
  266: 
  267:                 fflush(stdout);
  268:             }
  269: 
  270:             if (rpl_arguments.type_erreur == 'S')
  271:             {
  272:                 (*s_etat_processus).erreur_systeme =
  273:                         d_es_execution_bibliotheque;
  274:             }
  275:             else
  276:             {
  277:                 (*s_etat_processus).erreur_execution =
  278:                         d_ex_execution_bibliotheque;
  279:             }
  280:         }
  281: 
  282:         (*s_etat_processus).l_base_pile = rpl_arguments.l_base_pile;
  283:         (*s_etat_processus).l_base_pile_last = rpl_arguments.l_base_pile_last;
  284: 
  285:         for(i = 0; i < 8; i++)
  286:         {
  287:             (*s_etat_processus).drapeaux_etat[i] =
  288:                     rpl_arguments.drapeaux_etat[i];
  289:         }
  290: 
  291:         l_element_courant = (*s_etat_processus).l_base_pile;
  292:         (*s_etat_processus).hauteur_pile_operationnelle = 0;
  293: 
  294:         while(l_element_courant != NULL)
  295:         {
  296:             (*s_etat_processus).hauteur_pile_operationnelle++;
  297:             l_element_courant = (*l_element_courant).suivant;
  298:         }
  299:     }
  300:     else
  301:     {
  302:         printf("%s\n", message);
  303: 
  304:         if (pthread_mutex_unlock(&mutex) != 0)
  305:         {
  306:             (*s_etat_processus).erreur_systeme = d_es_processus;
  307:             return(NULL);
  308:         }
  309:     }
  310: 
  311:     if (pthread_mutex_lock(&mutex) != 0)
  312:     {
  313:         (*s_etat_processus).erreur_systeme = d_es_processus;
  314:         return(NULL);
  315:     }
  316: 
  317:     dlerror();
  318:     fonction = dlsym(descripteur_bibliotheque, "__external_symbols");
  319: 
  320:     if (fonction == NULL)
  321:     {
  322:         if ((message = dlerror()) != NULL)
  323:         {
  324:             printf("%s\n", message);
  325: 
  326:             if (pthread_mutex_unlock(&mutex) != 0)
  327:             {
  328:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  329:                 return(NULL);
  330:             }
  331: 
  332:             (*s_etat_processus).erreur_execution = d_ex_erreur_bibliotheque;
  333:             return(NULL);
  334:         }
  335:     }
  336:  
  337:     if (pthread_mutex_unlock(&mutex) != 0)
  338:     {
  339:         (*s_etat_processus).erreur_systeme = d_es_processus;
  340:         return(NULL);
  341:     }
  342: 
  343:     /*
  344:      * Ajout des symboles externes
  345:      */
  346: 
  347:     if ((tableau = (unsigned char **) (*fonction)((&nombre_symboles),
  348:             d_version_rpl)) == NULL)
  349:     {
  350:         /*
  351:          * Nombre symboles :
  352:          * 0    : aucun symbole exporté
  353:          * >0   : nombre de symboles exportés
  354:          * -1   : version de bibliothèque incompatible
  355:          */
  356: 
  357:         if (nombre_symboles == 0)
  358:         {
  359:             (*s_etat_processus).erreur_execution = d_ex_aucun_symbole;
  360:         }
  361:         else if (nombre_symboles == -1)
  362:         {
  363:             (*s_etat_processus).erreur_execution = d_ex_version_bibliotheque;
  364:         }
  365:         else
  366:         {
  367:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  368:         }
  369: 
  370:         return(NULL);
  371:     }
  372: 
  373:     if (((*s_etat_processus).s_instructions_externes = realloc(
  374:             (*s_etat_processus).s_instructions_externes,
  375:             ((*s_etat_processus).nombre_instructions_externes + nombre_symboles)
  376:             * sizeof(struct_instruction_externe))) == NULL)
  377:     {
  378:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  379:         return(NULL);
  380:     }
  381: 
  382:     for(i = 0; i < nombre_symboles; i++)
  383:     {
  384:         (*s_etat_processus).s_instructions_externes[(*s_etat_processus)
  385:                 .nombre_instructions_externes].descripteur_bibliotheque =
  386:                 descripteur_bibliotheque;
  387: 
  388:         if (((*s_etat_processus).s_instructions_externes[(*s_etat_processus)
  389:                 .nombre_instructions_externes].nom =
  390:                 malloc((strlen(index(tableau[i], '$') + 1) + 1) *
  391:                 sizeof(unsigned char))) == NULL)
  392:         {
  393:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  394:             return(NULL);
  395:         }
  396: 
  397:         strcpy((*s_etat_processus).s_instructions_externes[(*s_etat_processus)
  398:                 .nombre_instructions_externes].nom,
  399:                 index(tableau[i], '$') + 1);
  400: 
  401:         *(index(tableau[i], '$')) = d_code_fin_chaine;
  402: 
  403:         if (((*s_etat_processus).s_instructions_externes[(*s_etat_processus)
  404:                 .nombre_instructions_externes].nom_bibliotheque = malloc(
  405:                 (strlen(tableau[i]) + 1) * sizeof(unsigned char))) == NULL)
  406:         {
  407:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  408:             return(NULL);
  409:         }
  410: 
  411:         strcpy((*s_etat_processus).s_instructions_externes[(*s_etat_processus)
  412:                 .nombre_instructions_externes].nom_bibliotheque, tableau[i]);
  413:         (*s_etat_processus).nombre_instructions_externes++;
  414: 
  415:         free(tableau[i]);
  416:     }
  417: 
  418:     /*
  419:      * Ajout de la nouvelle bibliothèque
  420:      */
  421: 
  422:     if ((l_nouvel_element = (struct_liste_chainee *)
  423:             malloc(sizeof(struct_liste_chainee))) == NULL)
  424:     {
  425:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  426:         return(NULL);
  427:     }
  428: 
  429:     if (((*l_nouvel_element).donnee = malloc(sizeof(struct_bibliotheque)))
  430:             == NULL)
  431:     {
  432:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  433:         return(NULL);
  434:     }
  435: 
  436:     (*((struct_bibliotheque *) (*l_nouvel_element).donnee)).descripteur =
  437:             descripteur_bibliotheque;
  438:     (*((struct_bibliotheque *) (*l_nouvel_element).donnee)).pid =
  439:             getpid();
  440:     (*((struct_bibliotheque *) (*l_nouvel_element).donnee)).tid =
  441:             pthread_self();
  442: 
  443:     if (((*((struct_bibliotheque *) (*l_nouvel_element).donnee)).nom =
  444:             malloc((strlen((*s_etat_processus).s_instructions_externes
  445:             [(*s_etat_processus).nombre_instructions_externes - 1]
  446:             .nom_bibliotheque) + 1) * sizeof(unsigned char))) == NULL)
  447:     {
  448:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  449:         return(NULL);
  450:     }
  451: 
  452:     strcpy((*((struct_bibliotheque *) (*l_nouvel_element).donnee)).nom,
  453:             (*s_etat_processus).s_instructions_externes
  454:             [(*s_etat_processus).nombre_instructions_externes - 1]
  455:             .nom_bibliotheque);
  456: 
  457:     (*l_nouvel_element).suivant = (*s_etat_processus).s_bibliotheques;
  458:     (*s_etat_processus).s_bibliotheques = l_nouvel_element;
  459: 
  460:     tri_base_symboles_externes(s_etat_processus);
  461: 
  462:     free(tableau);
  463: 
  464:     return(descripteur_bibliotheque);
  465: }
  466: 
  467: 
  468: /*
  469: ================================================================================
  470:   Procédure de retrait d'une bibliothèque dynamique
  471: ================================================================================
  472:   Entrée :
  473: --------------------------------------------------------------------------------
  474:   Sortie :
  475: --------------------------------------------------------------------------------
  476:   Effets de bord : néant
  477: ================================================================================
  478: */
  479: 
  480: logical1
  481: retrait_bibliotheque(struct_processus *s_etat_processus,
  482:         struct_bibliotheque *descripteur)
  483: {
  484:     char                        *message;
  485: 
  486:     logical1                    presence_bibliotheque;
  487: 
  488:     struct_instruction_externe  *registre;
  489: 
  490:     struct_liste_chainee        *l_element_courant;
  491:     struct_liste_chainee        *l_element_precedent;
  492: 
  493:     struct_rpl_arguments        rpl_arguments;
  494: 
  495:     unsigned char               *tampon;
  496: 
  497:     unsigned long               i;
  498:     unsigned long               j;
  499:     unsigned long               nombre_symboles_residuels;
  500: 
  501:     void                        (*onclosing)(struct_rpl_arguments *);
  502: 
  503:     l_element_courant = (*s_etat_processus).s_bibliotheques;
  504:     presence_bibliotheque = d_faux;
  505:     l_element_precedent = NULL;
  506: 
  507:     /*
  508:      * Recherche de la bibliothèque à supprimer
  509:      */
  510: 
  511:     while(l_element_courant != NULL)
  512:     {
  513:         if (((*((struct_bibliotheque *) (*l_element_courant).donnee))
  514:                 .descripteur == (*descripteur).descripteur) &&
  515:                 ((*((struct_bibliotheque *) (*l_element_courant).donnee)).pid
  516:                 == getpid()) && (pthread_equal((*((struct_bibliotheque *)
  517:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  518:         {
  519:             presence_bibliotheque = d_vrai;
  520:             break;
  521:         }
  522: 
  523:         l_element_precedent = l_element_courant;
  524:         l_element_courant = (*l_element_courant).suivant;
  525:     }
  526: 
  527:     if (presence_bibliotheque == d_vrai)
  528:     {
  529:         if (pthread_mutex_lock(&mutex) != 0)
  530:         {
  531:             (*s_etat_processus).erreur_systeme = d_es_processus;
  532:             return(d_erreur);
  533:         }
  534: 
  535:         dlerror();
  536:         onclosing = dlsym((*descripteur).descripteur, "__runOnClosing");
  537: 
  538:         if (((message = dlerror()) == NULL) && (onclosing != NULL))
  539:         {
  540:             if (pthread_mutex_unlock(&mutex) != 0)
  541:             {
  542:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  543:                 return(d_erreur);
  544:             }
  545: 
  546:             rpl_arguments.l_base_pile = (*s_etat_processus).l_base_pile;
  547:             rpl_arguments.l_base_pile_last =
  548:                     (*s_etat_processus).l_base_pile_last;
  549: 
  550:             for(i = 0; i < 8; i++)
  551:             {
  552:                 rpl_arguments.drapeaux_etat[i] =
  553:                         (*s_etat_processus).drapeaux_etat[i];
  554:             }
  555: 
  556:             rpl_arguments.message_erreur = NULL;
  557:             rpl_arguments.type_erreur = 'E';
  558:             rpl_arguments.erreur = 0;
  559:             rpl_arguments.aide = ((*s_etat_processus).affichage_arguments
  560:                     == 'N') ? d_faux : d_vrai;
  561:             rpl_arguments.affichage_arguments = (*s_etat_processus)
  562:                     .affichage_arguments;
  563:             rpl_arguments.test_instruction =
  564:                     (*s_etat_processus).test_instruction;
  565:             rpl_arguments.constante_symbolique = (*s_etat_processus)
  566:                     .constante_symbolique;
  567:             rpl_arguments.instruction_valide = 'N';
  568:             rpl_arguments.s_etat_processus = s_etat_processus;
  569: 
  570:             (*s_etat_processus).erreur_execution = d_ex;
  571: 
  572:             if ((*s_etat_processus).profilage == d_vrai)
  573:             {
  574:                 if ((tampon = malloc((strlen((*descripteur).nom) + 14) *
  575:                         sizeof(unsigned char))) == NULL)
  576:                 {
  577:                     (*s_etat_processus).erreur_systeme =
  578:                             d_es_allocation_memoire;
  579:                     return(d_erreur);
  580:                 }
  581: 
  582:                 sprintf(tampon, "%s$runOnClosing", (*descripteur).nom);
  583:                 profilage(s_etat_processus, tampon);
  584:                 free(tampon);
  585: 
  586:                 if ((*s_etat_processus).erreur_systeme != d_es)
  587:                 {
  588:                     return(d_erreur);
  589:                 }
  590:             }
  591: 
  592: #           ifndef SEMAPHORES_NOMMES
  593:             if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
  594:             {
  595:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  596:                 return(d_erreur);
  597:             }
  598: #           else
  599:             if (sem_post((*s_etat_processus).semaphore_fork) != 0)
  600:             {
  601:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  602:                 return(d_erreur);
  603:             }
  604: #           endif
  605: 
  606:             (*onclosing)(&rpl_arguments);
  607: 
  608: #           ifndef SEMAPHORES_NOMMES
  609:             while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
  610:             {
  611:                 if (errno != EINTR)
  612:                 {
  613:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  614:                     return(d_erreur);
  615:                 }
  616:             }
  617: #           else
  618:             while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
  619:             {
  620:                 if (errno != EINTR)
  621:                 {
  622:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  623:                     return(d_erreur);
  624:                 }
  625:             }
  626: #           endif
  627: 
  628:             if ((*s_etat_processus).profilage == d_vrai)
  629:             {
  630:                 profilage(s_etat_processus, NULL);
  631:             }
  632: 
  633:             (*s_etat_processus).nombre_arguments =
  634:                     rpl_arguments.nombre_arguments;
  635:             (*s_etat_processus).constante_symbolique = rpl_arguments
  636:                     .constante_symbolique;
  637:             (*s_etat_processus).instruction_valide = rpl_arguments
  638:                     .instruction_valide;
  639: 
  640:             if ((*s_etat_processus).test_instruction == 'Y')
  641:             {
  642:                 if ((*s_etat_processus).nombre_arguments == 0)
  643:                 {
  644:                     (*s_etat_processus).nombre_arguments = -1;
  645:                 }
  646:             }
  647: 
  648:             if (rpl_arguments.erreur != 0)
  649:             {
  650:                 if (((*s_etat_processus).arret_si_exception == d_vrai) ||
  651:                         (rpl_arguments.type_erreur == 'S'))
  652:                 {
  653:                     if (test_cfsf(s_etat_processus, 51) == d_faux)
  654:                     {
  655:                         printf("%s", ds_beep);
  656:                     }
  657: 
  658:                     if (rpl_arguments.type_erreur == 'S')
  659:                     {
  660:                         (*s_etat_processus).derniere_erreur_execution = -1;
  661: 
  662:                         if ((*s_etat_processus).langue == 'F')
  663:                         {
  664:                             printf("+++Système : Fonction dynamique "
  665:                                     "%s (ligne %lld)\n",
  666:                                     "onClosing" , rpl_arguments.erreur);
  667:                         }
  668:                         else
  669:                         {
  670:                             printf("+++System : %s dynamic function "
  671:                                     "(line %lld)\n",
  672:                                     "onClosing", rpl_arguments.erreur);
  673:                         }
  674:                     }
  675:                     else
  676:                     {
  677:                         (*s_etat_processus).derniere_erreur_systeme = -1;
  678: 
  679:                         if ((*s_etat_processus).langue == 'F')
  680:                         {
  681:                             printf("+++Erreur : Fonction dynamique %s "
  682:                                     "(ligne %lld)\n",
  683:                                     "onClosing", rpl_arguments.erreur);
  684:                         }
  685:                         else
  686:                         {
  687:                             printf("+++Error : %s dynamic function "
  688:                                     "(line %lld)\n",
  689:                                     "onClosing", rpl_arguments.erreur);
  690:                         }
  691:                     }
  692: 
  693:                     if (rpl_arguments.message_erreur != NULL)
  694:                     {
  695:                         printf("%s\n", rpl_arguments.message_erreur);
  696:                     }
  697: 
  698:                     fflush(stdout);
  699:                 }
  700: 
  701:                 if (rpl_arguments.type_erreur == 'S')
  702:                 {
  703:                     (*s_etat_processus).erreur_systeme =
  704:                             d_es_execution_bibliotheque;
  705:                 }
  706:                 else
  707:                 {
  708:                     (*s_etat_processus).erreur_execution =
  709:                             d_ex_execution_bibliotheque;
  710:                 }
  711:             }
  712: 
  713:             (*s_etat_processus).l_base_pile = rpl_arguments.l_base_pile;
  714:             (*s_etat_processus).l_base_pile_last =
  715:                     rpl_arguments.l_base_pile_last;
  716: 
  717:             for(i = 0; i < 8; i++)
  718:             {
  719:                 (*s_etat_processus).drapeaux_etat[i] =
  720:                         rpl_arguments.drapeaux_etat[i];
  721:             }
  722: 
  723:             l_element_courant = (*s_etat_processus).l_base_pile;
  724:             (*s_etat_processus).hauteur_pile_operationnelle = 0;
  725: 
  726:             while(l_element_courant != NULL)
  727:             {
  728:                 (*s_etat_processus).hauteur_pile_operationnelle++;
  729:                 l_element_courant = (*l_element_courant).suivant;
  730:             }
  731:         }
  732:         else
  733:         {
  734:             printf("%s\n", message);
  735: 
  736:             if (pthread_mutex_unlock(&mutex) != 0)
  737:             {
  738:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  739:                 return(d_erreur);
  740:             }
  741:         }
  742: 
  743:         /*
  744:          * Retrait de la bibliothèque de la pile
  745:          */
  746: 
  747:         dlclose((*descripteur).descripteur);
  748: 
  749:         l_element_courant = (*s_etat_processus).s_bibliotheques;
  750: 
  751:         while(l_element_courant != NULL)
  752:         {
  753:             if ((*((struct_bibliotheque *) (*l_element_courant).donnee))
  754:                     .descripteur == (*descripteur).descripteur)
  755:             {
  756:                 break;
  757:             }
  758: 
  759:             l_element_precedent = l_element_courant;
  760:             l_element_courant = (*l_element_courant).suivant;
  761:         }
  762: 
  763:         if (l_element_precedent == NULL)
  764:         {
  765:             (*s_etat_processus).s_bibliotheques = (*l_element_courant).suivant;
  766:         }
  767:         else
  768:         {
  769:             (*l_element_precedent).suivant = (*l_element_courant).suivant;
  770:         }
  771: 
  772:         free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom);
  773:         free((*l_element_courant).donnee);
  774:         free(l_element_courant);
  775: 
  776:         /*
  777:          * Retrait des symboles associés à la bibliothèque
  778:          */
  779: 
  780:         nombre_symboles_residuels = 0;
  781: 
  782:         for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++)
  783:         {
  784:             if ((*s_etat_processus).s_instructions_externes[i]
  785:                     .descripteur_bibliotheque != (*descripteur).descripteur)
  786:             {
  787:                 nombre_symboles_residuels++;
  788:             }
  789:         }
  790: 
  791:         if (nombre_symboles_residuels == 0)
  792:         {
  793:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  794:                     i++)
  795:             {
  796:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  797:                 free((*s_etat_processus).s_instructions_externes[i]
  798:                         .nom_bibliotheque);
  799:             }
  800: 
  801:             free((*s_etat_processus).s_instructions_externes);
  802:             (*s_etat_processus).s_instructions_externes = NULL;
  803:         }
  804:         else
  805:         {
  806:             registre = (*s_etat_processus).s_instructions_externes;
  807: 
  808:             if (((*s_etat_processus).s_instructions_externes =
  809:                     malloc(nombre_symboles_residuels *
  810:                     sizeof(struct_instruction_externe))) == NULL)
  811:             {
  812:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  813: 
  814:                 return(d_erreur);
  815:             }
  816: 
  817:             for(i = j = 0; i < (*s_etat_processus).nombre_instructions_externes;
  818:                     i++)
  819:             {
  820:                 if (registre[i].descripteur_bibliotheque !=
  821:                         (*descripteur).descripteur)
  822:                 {
  823:                     (*s_etat_processus).s_instructions_externes[j].nom =
  824:                             registre[i].nom;
  825:                     (*s_etat_processus).s_instructions_externes[j]
  826:                             .nom_bibliotheque = registre[i].nom_bibliotheque;
  827:                     (*s_etat_processus).s_instructions_externes[j]
  828:                             .descripteur_bibliotheque = registre[i]
  829:                             .descripteur_bibliotheque;
  830:                     j++;
  831:                 }
  832:                 else
  833:                 {
  834:                     free(registre[i].nom);
  835:                     free(registre[i].nom_bibliotheque);
  836:                 }
  837:             }
  838: 
  839:             free(registre);
  840:         }
  841: 
  842:         (*s_etat_processus).nombre_instructions_externes =
  843:                 nombre_symboles_residuels;
  844: 
  845:         return(d_absence_erreur);
  846:     }
  847:     else
  848:     {
  849:         (*s_etat_processus).erreur_execution = d_ex_erreur_bibliotheque;
  850: 
  851:         return(d_erreur);
  852:     }
  853: }
  854: 
  855: 
  856: /*
  857: ================================================================================
  858:   Procédure d'exécution d'une fonction d'une bibliothèque
  859: ================================================================================
  860:   Entrée :
  861: --------------------------------------------------------------------------------
  862:   Sortie :
  863: --------------------------------------------------------------------------------
  864:   Effets de bord : néant
  865: ================================================================================
  866: */
  867: 
  868: logical1
  869: execution_fonction_de_bibliotheque(struct_processus *s_etat_processus,
  870:         unsigned char *nom_fonction, unsigned char *bibliotheque)
  871: {
  872:     logical1                        presence_bibliotheque;
  873:     logical1                        unicite_symbole;
  874: 
  875:     long                            difference;
  876:     long                            difference_inferieure;
  877:     long                            difference_superieure;
  878:     long                            i;
  879: 
  880:     struct_liste_chainee            *l_element_courant;
  881: 
  882:     struct_rpl_arguments            rpl_arguments;
  883: 
  884:     unsigned char                   *nom_fonction_externe;
  885:     unsigned char                   *tampon;
  886: 
  887:     unsigned long                   borne_inferieure;
  888:     unsigned long                   borne_superieure;
  889:     unsigned long                   moyenne;
  890:     unsigned long                   nombre_iterations_maximal;
  891:     unsigned long                   ordre_iteration;
  892: 
  893:     void                            (*fonction)(struct_rpl_arguments *);
  894: 
  895:     /*
  896:      * Recherche dichotomique de la définition externe
  897:      */
  898: 
  899:     if ((*s_etat_processus).nombre_instructions_externes == 0)
  900:     {
  901:         return(d_faux);
  902:     }
  903: 
  904:     if (bibliotheque != NULL)
  905:     {
  906:         presence_bibliotheque = d_faux;
  907:         l_element_courant = (*s_etat_processus).s_bibliotheques;
  908: 
  909:         while(l_element_courant != NULL)
  910:         {
  911:             if (strcmp((*((struct_bibliotheque *) (*l_element_courant).donnee))
  912:                     .nom, bibliotheque) == 0)
  913:             {
  914:                 presence_bibliotheque = d_vrai;
  915:                 break;
  916:             }
  917: 
  918:             l_element_courant = (*l_element_courant).suivant;
  919:         }
  920: 
  921:         if (presence_bibliotheque == d_faux)
  922:         {
  923:             return(d_faux);
  924:         }
  925:     }
  926: 
  927:     ordre_iteration = 0;
  928:     nombre_iterations_maximal = ((unsigned long)
  929:             (log((*s_etat_processus).nombre_instructions_externes) / log(2)))
  930:             + 2;
  931: 
  932:     borne_inferieure = 0;
  933:     borne_superieure = (*s_etat_processus).nombre_instructions_externes - 1;
  934: 
  935:     do
  936:     {
  937:         moyenne = (borne_inferieure + borne_superieure) / 2;
  938:         ordre_iteration++;
  939: 
  940:         if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))
  941:                 == (borne_inferieure + borne_superieure))
  942:         {
  943:             difference = strcmp(nom_fonction, (*s_etat_processus)
  944:                     .s_instructions_externes[moyenne].nom);
  945: 
  946:             if (difference != 0)
  947:             {
  948:                 if (difference > 0)
  949:                 {
  950:                     borne_inferieure = moyenne;
  951:                 }
  952:                 else
  953:                 {
  954:                     borne_superieure = moyenne;
  955:                 }
  956:             }
  957:         }
  958:         else
  959:         {
  960:             difference_inferieure = strcmp(nom_fonction,
  961:                     (*s_etat_processus).s_instructions_externes[moyenne].nom);
  962:             difference_superieure = strcmp(nom_fonction,
  963:                     (*s_etat_processus).s_instructions_externes[moyenne + 1]
  964:                     .nom);
  965: 
  966:             if (difference_inferieure == 0)
  967:             {
  968:                 difference = 0;
  969:             }
  970:             else if (difference_superieure == 0)
  971:             {
  972:                 difference = 0;
  973:                 moyenne++;
  974:             }
  975:             else
  976:             {
  977:                 difference = difference_inferieure;
  978: 
  979:                 if (difference > 0)
  980:                 {
  981:                     borne_inferieure = moyenne;
  982:                 }
  983:                 else
  984:                 {
  985:                     borne_superieure = moyenne;
  986:                 }
  987:             }
  988:         }
  989:     } while((difference != 0) &&
  990:             (ordre_iteration <= nombre_iterations_maximal));
  991: 
  992:     if (ordre_iteration > nombre_iterations_maximal)
  993:     {
  994:         return(d_faux);
  995:     }
  996: 
  997:     if (bibliotheque != NULL)
  998:     { // Nom de la bibliothèque spécifié
  999:         if (strcmp((*s_etat_processus).s_instructions_externes[moyenne]
 1000:                 .nom_bibliotheque, bibliotheque) > 0)
 1001:         {
 1002:             i = moyenne;
 1003: 
 1004:             while(i >= 0)
 1005:             {
 1006:                 if (strcmp((*s_etat_processus).s_instructions_externes[i]
 1007:                         .nom, nom_fonction) != 0)
 1008:                 {
 1009:                     break;
 1010:                 }
 1011:                 else if (strcmp((*s_etat_processus).s_instructions_externes[i]
 1012:                         .nom_bibliotheque, bibliotheque) == 0)
 1013:                 {
 1014:                     break;
 1015:                 }
 1016: 
 1017:                 i--;
 1018:             }
 1019: 
 1020:             moyenne = i;
 1021:         }
 1022:         else if (strcmp((*s_etat_processus).s_instructions_externes[moyenne]
 1023:                 .nom_bibliotheque, bibliotheque) < 0)
 1024:         {
 1025:             i = moyenne;
 1026: 
 1027:             while((unsigned long) i <
 1028:                     (*s_etat_processus).nombre_instructions_externes)
 1029:             {
 1030:                 if (strcmp((*s_etat_processus).s_instructions_externes[i]
 1031:                         .nom, nom_fonction) != 0)
 1032:                 {
 1033:                     break;
 1034:                 }
 1035:                 else if (strcmp((*s_etat_processus).s_instructions_externes[i]
 1036:                         .nom_bibliotheque, bibliotheque) == 0)
 1037:                 {
 1038:                     break;
 1039:                 }
 1040: 
 1041:                 i++;
 1042:             }
 1043: 
 1044:             moyenne = i;
 1045:         }
 1046:     }
 1047:     else
 1048:     { // Nom de la bibliothèque non spécifié
 1049: 
 1050:         /*
 1051:          * Vérification de l'unicité du symbole
 1052:          */
 1053: 
 1054:         unicite_symbole = d_vrai;
 1055: 
 1056:         if (moyenne > 0)
 1057:         {
 1058:             if (strcmp((*s_etat_processus).s_instructions_externes
 1059:                     [moyenne - 1].nom, nom_fonction) == 0)
 1060:             {
 1061:                 unicite_symbole = d_faux;
 1062:             }
 1063:         }
 1064: 
 1065:         if ((moyenne + 1) < (*s_etat_processus)
 1066:                 .nombre_instructions_externes)
 1067:         {
 1068:             if (strcmp((*s_etat_processus).s_instructions_externes
 1069:                     [moyenne + 1].nom, nom_fonction) == 0)
 1070:             {
 1071:                 unicite_symbole = d_faux;
 1072:             }
 1073:         }
 1074: 
 1075:         if (unicite_symbole == d_faux)
 1076:         {
 1077:             (*s_etat_processus).erreur_execution = d_ex_definition_ambigue;
 1078:             return(d_faux);
 1079:         }
 1080:     }
 1081: 
 1082:     if ((nom_fonction_externe = malloc((strlen(nom_fonction) + 12)
 1083:             * sizeof(unsigned char))) == NULL)
 1084:     {
 1085:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1086:         return(d_faux);
 1087:     }
 1088: 
 1089:     sprintf(nom_fonction_externe, "__external_%s", nom_fonction);
 1090: 
 1091:     if (pthread_mutex_lock(&mutex) != 0)
 1092:     {
 1093:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1094:         return(d_faux);
 1095:     }
 1096: 
 1097:     dlerror();
 1098:     fonction = dlsym((*s_etat_processus).s_instructions_externes
 1099:             [moyenne].descripteur_bibliotheque, nom_fonction_externe);
 1100: 
 1101:     free(nom_fonction_externe);
 1102: 
 1103:     /*
 1104:      * Vérification de la présence du symbole
 1105:      */
 1106: 
 1107:     if (fonction == NULL)
 1108:     {
 1109:         if (dlerror() != NULL)
 1110:         {
 1111:             if (pthread_mutex_unlock(&mutex) != 0)
 1112:             {
 1113:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1114:                 return(d_faux);
 1115:             }
 1116: 
 1117:             return(d_faux);
 1118:         }
 1119:     }
 1120: 
 1121:     if (pthread_mutex_unlock(&mutex) != 0)
 1122:     {
 1123:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1124:         return(d_faux);
 1125:     }
 1126: 
 1127:     /*
 1128:      * Exécution de la fonction externe
 1129:      */
 1130: 
 1131:     rpl_arguments.l_base_pile = (*s_etat_processus).l_base_pile;
 1132:     rpl_arguments.l_base_pile_last = (*s_etat_processus).l_base_pile_last;
 1133: 
 1134:     for(i = 0; i < 8; i++)
 1135:     {
 1136:         rpl_arguments.drapeaux_etat[i] =
 1137:                 (*s_etat_processus).drapeaux_etat[i];
 1138:     }
 1139: 
 1140:     rpl_arguments.message_erreur = NULL;
 1141:     rpl_arguments.type_erreur = 'E';
 1142:     rpl_arguments.erreur = 0;
 1143:     rpl_arguments.aide = ((*s_etat_processus).affichage_arguments
 1144:             == 'N') ? d_faux : d_vrai;
 1145:     rpl_arguments.affichage_arguments = (*s_etat_processus)
 1146:             .affichage_arguments;
 1147:     rpl_arguments.test_instruction = (*s_etat_processus).test_instruction;
 1148:     rpl_arguments.constante_symbolique = (*s_etat_processus)
 1149:             .constante_symbolique;
 1150:     rpl_arguments.instruction_valide = 'N';
 1151:     rpl_arguments.s_etat_processus = s_etat_processus;
 1152: 
 1153:     (*s_etat_processus).erreur_execution = d_ex;
 1154: 
 1155:     if ((*s_etat_processus).profilage == d_vrai)
 1156:     {
 1157:         if ((tampon = malloc(strlen((*s_etat_processus)
 1158:                 .s_instructions_externes[moyenne].nom_bibliotheque)
 1159:                 + strlen(nom_fonction) + 2)) == NULL)
 1160:         {
 1161:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1162:             return(d_faux);
 1163:         }
 1164: 
 1165:         sprintf(tampon, "%s$%s", (*s_etat_processus).s_instructions_externes
 1166:                 [moyenne].nom_bibliotheque, nom_fonction);
 1167:         profilage(s_etat_processus, tampon);
 1168:         free(tampon);
 1169: 
 1170:         if ((*s_etat_processus).erreur_systeme != d_es)
 1171:         {
 1172:             return(d_faux);
 1173:         }
 1174:     }
 1175: 
 1176: #   ifndef SEMAPHORES_NOMMES
 1177:     if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 1178:     {
 1179:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1180:         return(d_faux);
 1181:     }
 1182: #   else
 1183:     if (sem_post((*s_etat_processus).semaphore_fork) != 0)
 1184:     {
 1185:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1186:         return(d_faux);
 1187:     }
 1188: #   endif
 1189: 
 1190:     (*fonction)(&rpl_arguments);
 1191: 
 1192: #   ifndef SEMAPHORES_NOMMES
 1193:     while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
 1194:     {
 1195:         if (errno != EINTR)
 1196:         {
 1197:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1198:             return(d_faux);
 1199:         }
 1200:     }
 1201: #   else
 1202:     while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
 1203:     {
 1204:         if (errno != EINTR)
 1205:         {
 1206:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1207:             return(d_faux);
 1208:         }
 1209:     }
 1210: #   endif
 1211: 
 1212:     if ((*s_etat_processus).profilage == d_vrai)
 1213:     {
 1214:         profilage(s_etat_processus, NULL);
 1215:     }
 1216: 
 1217:     (*s_etat_processus).nombre_arguments = rpl_arguments.nombre_arguments;
 1218:     (*s_etat_processus).constante_symbolique = rpl_arguments
 1219:             .constante_symbolique;
 1220:     (*s_etat_processus).instruction_valide = rpl_arguments
 1221:             .instruction_valide;
 1222: 
 1223:     if ((*s_etat_processus).test_instruction == 'Y')
 1224:     {
 1225:         if ((*s_etat_processus).nombre_arguments == 0)
 1226:         {
 1227:             (*s_etat_processus).nombre_arguments = -1;
 1228:         }
 1229:     }
 1230: 
 1231:     if (rpl_arguments.erreur != 0)
 1232:     {
 1233:         if (((*s_etat_processus).arret_si_exception == d_vrai) ||
 1234:                 (rpl_arguments.type_erreur == 'S'))
 1235:         {
 1236:             if (test_cfsf(s_etat_processus, 51) == d_faux)
 1237:             {
 1238:                 printf("%s", ds_beep);
 1239:             }
 1240: 
 1241:             if (rpl_arguments.type_erreur == 'S')
 1242:             {
 1243:                 (*s_etat_processus).derniere_erreur_execution = -1;
 1244: 
 1245:                 if ((*s_etat_processus).langue == 'F')
 1246:                 {
 1247:                     printf("+++Système : Fonction dynamique %s (ligne %lld)\n",
 1248:                             nom_fonction, rpl_arguments.erreur);
 1249:                 }
 1250:                 else
 1251:                 {
 1252:                     printf("+++System : %s dynamic function (line %lld)\n",
 1253:                             nom_fonction, rpl_arguments.erreur);
 1254:                 }
 1255:             }
 1256:             else
 1257:             {
 1258:                 (*s_etat_processus).derniere_erreur_systeme = -1;
 1259: 
 1260:                 if ((*s_etat_processus).langue == 'F')
 1261:                 {
 1262:                     printf("+++Erreur : Fonction dynamique %s (ligne %lld)\n",
 1263:                             nom_fonction, rpl_arguments.erreur);
 1264:                 }
 1265:                 else
 1266:                 {
 1267:                     printf("+++Error : %s dynamic function (line %lld)\n",
 1268:                             nom_fonction, rpl_arguments.erreur);
 1269:                 }
 1270:             }
 1271: 
 1272:             if (rpl_arguments.message_erreur != NULL)
 1273:             {
 1274:                 printf("%s\n", rpl_arguments.message_erreur);
 1275:             }
 1276: 
 1277:             fflush(stdout);
 1278:         }
 1279: 
 1280:         if (rpl_arguments.type_erreur == 'S')
 1281:         {
 1282:             (*s_etat_processus).erreur_systeme =
 1283:                     d_es_execution_bibliotheque;
 1284:         }
 1285:         else
 1286:         {
 1287:             (*s_etat_processus).erreur_execution =
 1288:                     d_ex_execution_bibliotheque;
 1289:         }
 1290:     }
 1291: 
 1292:     (*s_etat_processus).l_base_pile = rpl_arguments.l_base_pile;
 1293:     (*s_etat_processus).l_base_pile_last = rpl_arguments.l_base_pile_last;
 1294: 
 1295:     for(i = 0; i < 8; i++)
 1296:     {
 1297:         (*s_etat_processus).drapeaux_etat[i] =
 1298:                 rpl_arguments.drapeaux_etat[i];
 1299:     }
 1300: 
 1301:     l_element_courant = (*s_etat_processus).l_base_pile;
 1302:     (*s_etat_processus).hauteur_pile_operationnelle = 0;
 1303: 
 1304:     while(l_element_courant != NULL)
 1305:     {
 1306:         (*s_etat_processus).hauteur_pile_operationnelle++;
 1307:         l_element_courant = (*l_element_courant).suivant;
 1308:     }
 1309: 
 1310: #undef return
 1311:     return(d_vrai);
 1312: }
 1313: 
 1314: 
 1315: /*
 1316: ================================================================================
 1317:   Wrapper vers une fonction intrinsèque
 1318: ================================================================================
 1319:   Entrée :
 1320: --------------------------------------------------------------------------------
 1321:   Sortie :
 1322: --------------------------------------------------------------------------------
 1323:   Effets de bord : néant
 1324: ================================================================================
 1325: */
 1326: 
 1327: int
 1328: wrapper_instruction_intrinseque(void (*fonction)(),
 1329:         struct_rpl_arguments *rpl_arguments)
 1330: {
 1331:     int                     i;
 1332: 
 1333:     logical1                registre31;
 1334: 
 1335:     struct_liste_chainee    *l_element_courant;
 1336: 
 1337:     struct_processus        *s_etat_processus;
 1338: 
 1339:     s_etat_processus = (*rpl_arguments).s_etat_processus;
 1340: 
 1341:     (*s_etat_processus).nombre_arguments = (*rpl_arguments).nombre_arguments;
 1342:     (*s_etat_processus).constante_symbolique = (*rpl_arguments)
 1343:             .constante_symbolique;
 1344:     (*s_etat_processus).instruction_valide = (*rpl_arguments)
 1345:             .instruction_valide;
 1346:     (*s_etat_processus).l_base_pile = (*rpl_arguments).l_base_pile;
 1347:     (*s_etat_processus).l_base_pile_last = (*rpl_arguments).l_base_pile_last;
 1348: 
 1349:     for(i = 0; i < 8; i++)
 1350:     {
 1351:         (*s_etat_processus).drapeaux_etat[i] =
 1352:                 (*rpl_arguments).drapeaux_etat[i];
 1353:     }
 1354: 
 1355:     l_element_courant = (*s_etat_processus).l_base_pile;
 1356:     (*s_etat_processus).hauteur_pile_operationnelle = 0;
 1357: 
 1358:     while(l_element_courant != NULL)
 1359:     {
 1360:         (*s_etat_processus).hauteur_pile_operationnelle++;
 1361:         l_element_courant = (*l_element_courant).suivant;
 1362:     }
 1363: 
 1364:     registre31 = test_cfsf(s_etat_processus, 31);
 1365:     cf(s_etat_processus, 31);
 1366: 
 1367:     (*fonction)(s_etat_processus);
 1368: 
 1369:     if (registre31 == d_vrai)
 1370:     {
 1371:         sf(s_etat_processus, 31);
 1372:     }
 1373:     else
 1374:     {
 1375:         cf(s_etat_processus, 31);
 1376:     }
 1377: 
 1378:     (*rpl_arguments).l_base_pile = (*s_etat_processus).l_base_pile;
 1379:     (*rpl_arguments).l_base_pile_last = (*s_etat_processus).l_base_pile_last;
 1380: 
 1381:     for(i = 0; i < 8; i++)
 1382:     {
 1383:         (*rpl_arguments).drapeaux_etat[i] =
 1384:                 (*s_etat_processus).drapeaux_etat[i];
 1385:     }
 1386: 
 1387:     (*rpl_arguments).message_erreur = NULL;
 1388:     (*rpl_arguments).type_erreur = 'E';
 1389:     (*rpl_arguments).erreur = 0;
 1390:     (*rpl_arguments).aide = ((*s_etat_processus).affichage_arguments
 1391:             == 'N') ? d_faux : d_vrai;
 1392:     (*rpl_arguments).affichage_arguments = (*s_etat_processus)
 1393:             .affichage_arguments;
 1394:     (*rpl_arguments).test_instruction = (*s_etat_processus).test_instruction;
 1395:     (*rpl_arguments).constante_symbolique = (*s_etat_processus)
 1396:             .constante_symbolique;
 1397:     (*rpl_arguments).instruction_valide = 'Y';
 1398:     (*rpl_arguments).s_etat_processus = s_etat_processus;
 1399: 
 1400:     if (((*s_etat_processus).erreur_execution != d_ex) ||
 1401:             ((*s_etat_processus).exception != d_ep))
 1402:     {
 1403:         return(1);
 1404:     }
 1405: 
 1406:     if ((*s_etat_processus).erreur_systeme != d_es)
 1407:     {
 1408:         return(2);
 1409:     }
 1410: 
 1411:     (*s_etat_processus).erreur_execution = d_ex;
 1412:     (*s_etat_processus).erreur_systeme = d_es;
 1413:     (*s_etat_processus).exception = d_ep;
 1414: 
 1415:     return(0);
 1416: }
 1417: 
 1418: 
 1419: /*
 1420: ================================================================================
 1421:   Procédure d'empilement d'un nouvel élément
 1422: ================================================================================
 1423:   Entrée :
 1424: --------------------------------------------------------------------------------
 1425:   Sortie :
 1426: --------------------------------------------------------------------------------
 1427:   Effets de bord : néant
 1428: ================================================================================
 1429: */
 1430: 
 1431: struct_liste_chainee *
 1432: empilement_pile_operationnelle(struct_rpl_arguments *s_rpl_arguments,
 1433:         struct_objet *s_objet)
 1434: {
 1435:     struct_liste_chainee        *l_ancienne_base_liste;
 1436:     struct_liste_chainee        *l_nouvelle_base_liste;
 1437: 
 1438:     l_ancienne_base_liste = (*s_rpl_arguments).l_base_pile;
 1439: 
 1440:     l_nouvelle_base_liste = (struct_liste_chainee *) malloc(
 1441:             sizeof(struct_liste_chainee));
 1442: 
 1443:     if (l_nouvelle_base_liste != NULL)
 1444:     {
 1445:         (*l_nouvelle_base_liste).donnee = s_objet;
 1446:         (*l_nouvelle_base_liste).suivant = l_ancienne_base_liste;
 1447:     }
 1448: 
 1449:     (*s_rpl_arguments).l_base_pile = l_nouvelle_base_liste;
 1450: 
 1451:     return l_nouvelle_base_liste;
 1452: }
 1453: 
 1454: 
 1455: /*
 1456: ================================================================================
 1457:   Procédure de dépilement d'un élément. L'emplacement est libéré dans la pile.
 1458: ================================================================================
 1459:   Entrée :
 1460: --------------------------------------------------------------------------------
 1461:   Sortie :
 1462: --------------------------------------------------------------------------------
 1463:   Effets de bord : néant
 1464: ================================================================================
 1465: */
 1466: 
 1467: struct_liste_chainee *
 1468: depilement_pile_operationnelle(struct_rpl_arguments *s_rpl_arguments,
 1469:         struct_objet **s_objet)
 1470: {
 1471:     struct_liste_chainee        *l_ancienne_base_liste;
 1472:     struct_liste_chainee        *l_nouvelle_base_liste;
 1473: 
 1474:     if ((*s_rpl_arguments).l_base_pile == NULL)
 1475:     {
 1476:         *s_objet = NULL;
 1477:         return(NULL);
 1478:     }
 1479:     else
 1480:     {
 1481:         l_ancienne_base_liste = (*s_rpl_arguments).l_base_pile;
 1482:         l_nouvelle_base_liste = (*l_ancienne_base_liste).suivant;
 1483: 
 1484:         *s_objet = (*l_ancienne_base_liste).donnee;
 1485:         free(l_ancienne_base_liste);
 1486: 
 1487:         (*s_rpl_arguments).l_base_pile = l_nouvelle_base_liste;
 1488: 
 1489:         return(l_nouvelle_base_liste);
 1490:     }
 1491: }
 1492: 
 1493: 
 1494: /*
 1495: ================================================================================
 1496:   Procédure de sauvegarde des arguments dans la pile last
 1497: ================================================================================
 1498:   Entrée : structure processus et nombre d'aguments à empiler
 1499: --------------------------------------------------------------------------------
 1500:   Sortie : drapeau d'erreur de la structure rpl_arguments
 1501: --------------------------------------------------------------------------------
 1502:   Effets de bord : efface le précédent contenu de la pile LAST
 1503: ================================================================================
 1504: */
 1505: 
 1506: struct_liste_chainee *
 1507: sauvegarde_arguments(struct_rpl_arguments *s_rpl_arguments,
 1508:         unsigned long nombre_arguments)
 1509: {
 1510:     struct_liste_chainee            *l_ancienne_base_liste;
 1511:     struct_liste_chainee            *l_element_courant;
 1512:     struct_liste_chainee            *l_element_suivant;
 1513:     struct_liste_chainee            *l_nouvelle_base_liste;
 1514: 
 1515:     struct_objet                    *s_objet;
 1516: 
 1517:     logical1                        erreur;
 1518: 
 1519:     t_8_bits                        masque;
 1520: 
 1521:     unsigned char                   indice_bit;
 1522:     unsigned char                   indice_bloc;
 1523:     unsigned char                   indice_drapeau;
 1524:     unsigned char                   taille_bloc;
 1525: 
 1526:     unsigned long                   i;
 1527: 
 1528:     struct_processus                *s_etat_processus;
 1529: 
 1530:     (*s_rpl_arguments).erreur = 0;
 1531:     s_etat_processus = (*s_rpl_arguments).s_etat_processus;
 1532: 
 1533:     indice_drapeau = 31;
 1534:     indice_drapeau--;
 1535:     taille_bloc = sizeof(t_8_bits) * 8;
 1536:     indice_bloc = indice_drapeau / taille_bloc;
 1537:     indice_bit = indice_drapeau % taille_bloc;
 1538: 
 1539:     masque = ((t_8_bits) 1) << (taille_bloc - indice_bit - 1);
 1540: 
 1541:     if (((*s_rpl_arguments).drapeaux_etat[indice_bloc] & masque) == 0)
 1542:     {
 1543:         return (*s_rpl_arguments).l_base_pile_last;
 1544:     }
 1545:     
 1546:     erreur = d_absence_erreur;
 1547: 
 1548:     l_element_courant = (*s_rpl_arguments).l_base_pile_last;
 1549:     while(l_element_courant != NULL)
 1550:     {
 1551:         liberation(s_etat_processus, (*l_element_courant).donnee);
 1552:         l_element_suivant = (*l_element_courant).suivant;
 1553:         free(l_element_courant);
 1554:         l_element_courant = l_element_suivant;
 1555:     }
 1556: 
 1557:     (*s_rpl_arguments).l_base_pile_last = NULL;
 1558:     l_element_courant = (*s_rpl_arguments).l_base_pile;
 1559:     l_nouvelle_base_liste = (*s_rpl_arguments).l_base_pile_last;
 1560: 
 1561:     for(i = 0; ((i < nombre_arguments) && (erreur == d_absence_erreur)
 1562:             && (l_element_courant != NULL)); i++)
 1563:     {
 1564:         s_objet = copie_objet(s_etat_processus,
 1565:                 (*l_element_courant).donnee, 'P');
 1566: 
 1567:         if (s_objet != NULL)
 1568:         {
 1569:             l_ancienne_base_liste = l_nouvelle_base_liste;
 1570:             l_nouvelle_base_liste = (struct_liste_chainee *) malloc(
 1571:                     sizeof(struct_liste_chainee));
 1572: 
 1573:             if (l_nouvelle_base_liste != NULL)
 1574:             {
 1575:                 (*l_nouvelle_base_liste).donnee = s_objet;
 1576:                 (*l_nouvelle_base_liste).suivant = l_ancienne_base_liste;
 1577:                 
 1578:             }
 1579:             else
 1580:             {
 1581:                 erreur = d_erreur;
 1582:             }
 1583: 
 1584:             l_element_courant = (*l_element_courant).suivant;
 1585:         }
 1586:         else
 1587:         {
 1588:             erreur = d_erreur;
 1589:         }
 1590:     }
 1591: 
 1592:     if (i != nombre_arguments)
 1593:     {
 1594:         /*
 1595:          * Erreur système : la pile est vidée et la routine renvoie NULL.
 1596:          */
 1597: 
 1598:         l_element_courant = l_nouvelle_base_liste;
 1599:         while(l_element_courant != NULL)
 1600:         {
 1601:             liberation(s_etat_processus, (*l_element_courant).donnee);
 1602:             l_element_suivant = (*l_element_courant).suivant;
 1603:             free(l_element_courant);
 1604:             l_element_courant = l_element_suivant;
 1605:         }
 1606: 
 1607:         l_nouvelle_base_liste = NULL;
 1608:         (*s_rpl_arguments).erreur = i;
 1609:     }
 1610: 
 1611:     return(l_nouvelle_base_liste);
 1612: }
 1613: 
 1614: 
 1615: /*
 1616: ================================================================================
 1617:   Procédure de tri des symboles externes
 1618: 
 1619:   Principe du tri dit de Shell-Metzner
 1620: ================================================================================
 1621:   Entrée :
 1622: --------------------------------------------------------------------------------
 1623:   Sortie :
 1624: --------------------------------------------------------------------------------
 1625:   Effets de bord : néant
 1626: ================================================================================
 1627: */
 1628: 
 1629: void
 1630: tri_base_symboles_externes(struct_processus *s_etat_processus)
 1631: {
 1632:     logical1            terminaison_boucle;
 1633:     logical1            terminaison_boucle_1;
 1634:     logical1            terminaison_boucle_2;
 1635:     logical1            terminaison_boucle_3;
 1636: 
 1637:     signed long         indice_i;
 1638:     signed long         indice_j;
 1639:     signed long         indice_k;
 1640:     signed long         indice_l;
 1641: 
 1642:     unsigned long       borne_inferieure;
 1643:     unsigned long       borne_superieure;
 1644:     unsigned long       ecartement;
 1645:     unsigned long       indice;
 1646: 
 1647:     ecartement = (*s_etat_processus).nombre_instructions_externes;
 1648: 
 1649:     terminaison_boucle_1 = d_faux;
 1650: 
 1651:     do
 1652:     {
 1653:         ecartement = ecartement / 2;
 1654: 
 1655:         if (ecartement >= 1)
 1656:         {
 1657:             indice_j = 0;
 1658:             indice_k = (*s_etat_processus).nombre_instructions_externes
 1659:                     - ecartement;
 1660: 
 1661:             terminaison_boucle_2 = d_faux;
 1662: 
 1663:             do
 1664:             {
 1665:                 indice_i = indice_j;
 1666: 
 1667:                 terminaison_boucle_3 = d_faux;
 1668: 
 1669:                 do
 1670:                 {
 1671:                     indice_l = indice_i + ecartement;
 1672: 
 1673:                     if ((indice_i > 0) && (indice_l > 0))
 1674:                     {
 1675:                         if (strcmp(((*s_etat_processus).s_instructions_externes
 1676:                                 [indice_i - 1]).nom, ((*s_etat_processus)
 1677:                                 .s_instructions_externes[indice_l - 1]).nom)
 1678:                                 > 0)
 1679:                         {
 1680:                             swap((void *) &((*s_etat_processus)
 1681:                                     .s_instructions_externes
 1682:                                     [indice_i - 1]), (void *) 
 1683:                                     &((*s_etat_processus)
 1684:                                     .s_instructions_externes[indice_l - 1]),
 1685:                                     sizeof(struct_instruction_externe));
 1686: 
 1687:                             indice_i -= ecartement;
 1688: 
 1689:                             if (indice_i < 1)
 1690:                             {
 1691:                                 terminaison_boucle_3 = d_vrai;
 1692:                             }
 1693:                         }
 1694:                         else
 1695:                         {
 1696:                             terminaison_boucle_3 = d_vrai;
 1697:                         }
 1698:                     }
 1699:                     else
 1700:                     {
 1701:                         terminaison_boucle_3 = d_vrai;
 1702:                     }
 1703:                 } while(terminaison_boucle_3 == d_faux);
 1704: 
 1705:                 indice_j++;
 1706: 
 1707:                 if (indice_j > indice_k)
 1708:                 {
 1709:                     terminaison_boucle_2 = d_vrai;
 1710:                 }
 1711:             } while(terminaison_boucle_2 == d_faux);
 1712:         }
 1713:         else
 1714:         {
 1715:             terminaison_boucle_1 = d_vrai;
 1716:         }
 1717:     } while(terminaison_boucle_1 == d_faux);
 1718: 
 1719:     indice_i = 0;
 1720: 
 1721:     do
 1722:     {
 1723:         indice_j = indice_i;
 1724: 
 1725:         while(((unsigned long) (indice_i + 1) < (*s_etat_processus)
 1726:                 .nombre_instructions_externes) && (strcmp(((*s_etat_processus)
 1727:                 .s_instructions_externes[indice_i]).nom, ((*s_etat_processus)
 1728:                 .s_instructions_externes[indice_i + 1]).nom) == 0))
 1729:         {
 1730:             indice_i++;
 1731:         }
 1732: 
 1733:         borne_inferieure = indice_j;
 1734:         borne_superieure = indice_i;
 1735: 
 1736:         do
 1737:         {
 1738:             terminaison_boucle = d_vrai;
 1739: 
 1740:             for(indice = borne_inferieure + 1; indice <= borne_superieure;
 1741:                     indice++)
 1742:             {
 1743:                 if (strcmp((*s_etat_processus).s_instructions_externes[indice]
 1744:                         .nom_bibliotheque, (*s_etat_processus)
 1745:                         .s_instructions_externes[indice - 1].nom_bibliotheque)
 1746:                         < 0)
 1747:                 {
 1748:                     swap((void *) &((*s_etat_processus).s_instructions_externes
 1749:                             [indice - 1]), (void *) &((*s_etat_processus)
 1750:                             .s_instructions_externes[indice]),
 1751:                             sizeof(struct_instruction_externe));
 1752: 
 1753:                     terminaison_boucle = d_faux;
 1754:                 }
 1755:             }
 1756:         } while(terminaison_boucle == d_faux);
 1757: 
 1758:         indice_i++;
 1759:     } while((unsigned long) (indice_i + 1) <
 1760:             (*s_etat_processus).nombre_variables);
 1761: 
 1762:     return;
 1763: }
 1764: 
 1765: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>