File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.74: download - view: text, annotated - select for diffs - revision graph
Sun Jul 30 21:59:41 2017 UTC (6 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Ajout d'une série de patches pour gérer les instructions de type A->B
dans les bibliothèques externes.

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

CVSweb interface <joel.bertrand@systella.fr>