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