File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.57: download - view: text, annotated - select for diffs - revision graph
Sun Jan 26 18:21:29 2014 UTC (10 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_17, HEAD
Grosse mise à jour de ./tools et changement des copyrights. Correction d'une
variable non initialisée dans FORALL.

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

CVSweb interface <joel.bertrand@systella.fr>