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