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