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