File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.36: download - view: text, annotated - select for diffs - revision graph
Tue Sep 20 09:51:42 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Typo.

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

CVSweb interface <joel.bertrand@systella.fr>