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