File:  [local] / rpl / src / bibliotheques_externes.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Jan 26 15:22:44 2010 UTC (14 years, 3 months ago) by bertrand
Branches: JKB
CVS tags: start


Commit initial.

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

CVSweb interface <joel.bertrand@systella.fr>