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