File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.84: download - view: text, annotated - select for diffs - revision graph
Thu Jan 16 08:57:42 2020 UTC (4 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_32, HEAD
Correction d'un problème de compilation avec g++ 9.2 (cast dans rpl.h).

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

CVSweb interface <joel.bertrand@systella.fr>