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