File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.8: download - view: text, annotated - select for diffs - revision graph
Wed Apr 21 13:45:44 2010 UTC (14 years ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.0.15 !

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

CVSweb interface <joel.bertrand@systella.fr>