File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.34: download - view: text, annotated - select for diffs - revision graph
Wed Sep 14 17:55:59 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Suite des patches...

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

CVSweb interface <joel.bertrand@systella.fr>