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