File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.33: download - view: text, annotated - select for diffs - revision graph
Tue Aug 9 11:31:28 2011 UTC (12 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.3.

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

CVSweb interface <joel.bertrand@systella.fr>