File:
[local] /
rpl /
src /
gestion_variables.c
Revision
1.33:
download - view:
text,
annotated -
select for diffs -
revision graph
Sun Jun 19 17:48:27 2011 UTC (12 years, 10 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction de problèmes de pointeurs et de fuites de mémoire dans
la nouvelle gestion des variables. Ces nouvelles routines semblent maintenant
fonctionner sans problème dans le cas monothread et non compilé. Je
ne constate plus de fuite de mémoire ni d'opérations de lecture ou d'écriture
scabreuses.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.0
4: Copyright (C) 1989-2011 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:
26: /*
27: ================================================================================
28: Fonction de debug
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: static void
39: liste_variables_par_niveaux(struct_processus *s_etat_processus)
40: {
41: int c;
42:
43: logical1 fin;
44:
45: struct_liste_variables *l;
46:
47: struct_liste_chainee *e;
48:
49: printf("===========================================================\n");
50: printf(" Liste des variables par niveaux\n");
51: printf("===========================================================\n");
52:
53: printf("Backward\n");
54: l = (*s_etat_processus).l_liste_variables_par_niveau;
55: c = 0;
56: fin = d_faux;
57:
58: do
59: {
60: l = l->precedent;
61: e = l->liste;
62:
63: while(e != NULL)
64: {
65: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
66: e->donnee, ((struct_variable *) e->donnee)->niveau);
67: e = e->suivant;
68: c++;
69: if (c > 100)
70: {
71: fin = d_vrai;
72: break;
73: }
74: }
75:
76: printf("\n");
77:
78: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
79:
80: printf("Forward\n");
81: l = (*s_etat_processus).l_liste_variables_par_niveau;
82: c = 0;
83:
84: do
85: {
86: e = l->liste;
87:
88: while(e != NULL)
89: {
90: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
91: e->donnee, ((struct_variable *) e->donnee)->niveau);
92: e = e->suivant;
93: c++;
94: if (c > 100) exit(0);
95: }
96:
97: printf("\n");
98:
99: l = l->suivant;
100: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
101:
102: printf("===========================================================\n");
103:
104: if (fin == d_vrai) exit(0);
105:
106: return;
107: }
108:
109: static void
110: liste_variables_tas(struct_processus *s_etat_processus,
111: struct_arbre_variables *arbre)
112: {
113: int c;
114: int i;
115:
116: logical1 fin;
117:
118: struct_liste_variables *l;
119:
120: fin = d_faux;
121:
122: if ((*arbre).feuille != NULL)
123: {
124: printf("Feuille %p\n", (*arbre).feuille);
125:
126: printf(" Backward\n");
127:
128: l = (*arbre).feuille;
129: c = 0;
130: fin = d_faux;
131:
132: do
133: {
134: l = l->precedent;
135: c++;
136: if (c > 100)
137: {
138: fin = d_vrai;
139: break;
140: }
141: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
142: l->variable->niveau);
143: } while((*arbre).feuille != l);
144:
145: printf(" Forward\n");
146:
147: l = (*arbre).feuille;
148: c = 0;
149:
150: do
151: {
152: c++;
153: if (c > 100) exit(0);
154: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
155: l->variable->niveau);
156: l = l->suivant;
157: } while((*arbre).feuille != l);
158: }
159:
160: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
161: {
162: if ((*arbre).noeuds[i] != NULL)
163: {
164: liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
165: }
166: }
167:
168: if (fin == d_vrai) exit(0);
169:
170: return;
171: }
172:
173:
174: static void
175: liste_variables_par_feuilles(struct_processus *s_etat_processus)
176: {
177: printf("===========================================================\n");
178: printf(" Liste des variables sur le tas\n");
179: printf("===========================================================\n");
180:
181: liste_variables_tas(s_etat_processus,
182: (*s_etat_processus).s_arbre_variables);
183:
184: printf("===========================================================\n");
185:
186: return;
187: }
188:
189:
190: /*
191: ================================================================================
192: Routine de création d'une nouvelle variable
193: ================================================================================
194: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
195: dans le cas 'v', la variable est volatile.
196: dans le cas 's', elle est statique.
197: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
198: dans le cas 'p', la variable est privée.
199: dans le cas 's', elle est partagée.
200: --------------------------------------------------------------------------------
201: Sortie :
202: --------------------------------------------------------------------------------
203: Effets de bords : néant
204: ================================================================================
205: */
206:
207: static logical1
208: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
209: {
210: int i;
211:
212: logical1 niveau_acceptable;
213:
214: struct_liste_variables *l_nouvelle_variable;
215: struct_liste_variables *l_variable_candidate;
216:
217: struct_arbre_variables *l_variable_courante;
218: struct_arbre_variables *l_variable_precedente;
219:
220: struct_liste_chainee *l_nouvel_element;
221:
222: unsigned char *ptr;
223:
224: void *pointeur_variable_cree;
225:
226: if ((*s_etat_processus).s_arbre_variables == NULL)
227: {
228: if (((*s_etat_processus).s_arbre_variables =
229: malloc(sizeof(struct_arbre_variables))) == NULL)
230: {
231: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
232: return(d_erreur);
233: }
234:
235: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
236: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
237: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
238: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
239:
240: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
241: malloc((*s_etat_processus).nombre_caracteres_variables
242: * sizeof(struct_arbre_variables))) == NULL)
243: {
244: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
245: return(d_erreur);
246: }
247:
248: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
249: {
250: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
251: }
252: }
253:
254: l_variable_precedente = NULL;
255: l_variable_courante = (*s_etat_processus).s_arbre_variables;
256: ptr = (*s_variable).nom;
257:
258: while((*ptr) != d_code_fin_chaine)
259: {
260: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
261: printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
262: *ptr));
263:
264: if ((*l_variable_courante).noeuds[(*s_etat_processus)
265: .pointeurs_caracteres_variables[*ptr]] == NULL)
266: {
267: // Le noeud n'existe pas encore, on le crée et on le marque
268: // comme utilisé dans la structure parente.
269:
270: if (((*l_variable_courante).noeuds[(*s_etat_processus)
271: .pointeurs_caracteres_variables[*ptr]] =
272: malloc(sizeof(struct_arbre_variables))) == NULL)
273: {
274: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
275: return(d_erreur);
276: }
277:
278: (*l_variable_courante).noeuds_utilises++;
279:
280: // La feuille est par défaut vide et aucun élément du tableau noeuds
281: // (les branches qui peuvent être issues de ce nouveau noeud)
282: // n'est encore utilisée.
283:
284: (*(*l_variable_courante).noeuds[(*s_etat_processus)
285: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
286: (*(*l_variable_courante).noeuds[(*s_etat_processus)
287: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
288:
289: // Le champ noeud_pere de la structure créée pointe sur
290: // la structure parente et l'indice tableau_pere correspond à la
291: // position réelle dans le tableau noeuds[] de la structure parente
292: // du noeud courant. Cette valeur sera utilisée lors de la
293: // destruction du noeud pour annuler le pointeur contenu dans
294: // le tableau noeuds[] de la structure parente.
295:
296: (*(*l_variable_courante).noeuds[(*s_etat_processus)
297: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
298: l_variable_courante;
299: (*(*l_variable_courante).noeuds[(*s_etat_processus)
300: .pointeurs_caracteres_variables[*ptr]])
301: .indice_tableau_pere = (*s_etat_processus)
302: .pointeurs_caracteres_variables[*ptr];
303:
304: // Allocation du tableau noeuds[] et initialisation à zéro de
305: // tous les pointeurs.
306:
307: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
308: .pointeurs_caracteres_variables[*ptr]]).noeuds =
309: malloc((*s_etat_processus).nombre_caracteres_variables
310: * sizeof(struct_arbre_variables))) == NULL)
311: {
312: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
313: return(d_erreur);
314: }
315:
316: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
317: {
318: (*(*l_variable_courante).noeuds[(*s_etat_processus)
319: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
320: = NULL;
321: }
322: }
323:
324: l_variable_precedente = l_variable_courante;
325: l_variable_courante = (*l_variable_courante).noeuds
326: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
327: ptr++;
328: }
329:
330: if ((*l_variable_courante).feuille == NULL)
331: {
332: // Aucune variable de même nom préexiste. On alloue le premier
333: // élément de la liste doublement chaînée contenant toutes les
334: // variables de même nom. Cette liste boucle en premier lieu sur
335: // elle-même.
336:
337: if (((*l_variable_courante).feuille = malloc(
338: sizeof(struct_liste_variables))) == NULL)
339: {
340: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
341: return(d_erreur);
342: }
343:
344: (*(*l_variable_courante).feuille).suivant =
345: (*l_variable_courante).feuille;
346: (*(*l_variable_courante).feuille).precedent =
347: (*l_variable_courante).feuille;
348: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
349: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
350:
351: // Allocation de la variable sur l'élément de la liste.
352:
353: if (((*(*l_variable_courante).feuille).variable =
354: malloc(sizeof(struct_variable))) == NULL)
355: {
356: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
357: return(d_erreur);
358: }
359:
360: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
361: (*s_variable);
362: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
363: }
364: else
365: {
366: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
367: == NULL)
368: {
369: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
370: return(d_erreur);
371: }
372:
373: if ((*s_variable).niveau > 1)
374: {
375: // Cas d'une variable locale
376:
377: // Si le niveau de la dernière variable de même nom est
378: // supérieur au niveau de la variable locale que l'on veut
379: // enregistrer dans la liste, cette liste est incohérente.
380:
381: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
382: (*s_variable).niveau,
383: printf("Variable=\"%s\"\n", (*s_variable).nom));
384:
385: // On ajoute la variable à la liste existante.
386:
387: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
388: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
389: .precedent;
390: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
391: (*l_nouvelle_variable).noeud = l_variable_courante;
392: (*(*(*l_variable_courante).feuille).precedent).suivant =
393: l_nouvelle_variable;
394: (*(*l_variable_courante).feuille).precedent =
395: l_nouvelle_variable;
396: (*l_variable_courante).feuille = l_nouvelle_variable;
397:
398: if (((*(*l_variable_courante).feuille).variable =
399: malloc(sizeof(struct_variable))) == NULL)
400: {
401: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
402: return(d_erreur);
403: }
404:
405: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
406: = (*s_variable);
407: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
408: }
409: else
410: {
411: // Cas d'une variable globale (niveau 0 [définitions] ou 1
412: // [variables globales])
413:
414: l_variable_candidate = (*l_variable_courante).feuille;
415:
416: do
417: {
418: // S'il y a déjà une variable de même niveau, la pile
419: // est incohérente.
420:
421: BUG((*(*l_variable_candidate).variable).niveau ==
422: (*s_variable).niveau,
423: printf("Variable=\"%s\"\n", (*s_variable).nom));
424:
425: l_variable_candidate = (*l_variable_candidate).precedent;
426: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
427: ((*(*l_variable_candidate).variable).niveau <= 1));
428:
429: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
430: .niveau > 1)
431: {
432: // Ajout inconditionnel des variables de niveaux 0 et 1
433: }
434: else
435: {
436: l_variable_candidate = (*(*l_variable_courante).feuille)
437: .precedent;
438: }
439:
440: (*l_nouvelle_variable).suivant = l_variable_candidate;
441: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
442: .precedent;
443: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
444: (*l_nouvelle_variable).noeud = l_variable_courante;
445: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
446: (*l_variable_candidate).precedent = l_nouvelle_variable;
447:
448: if (((*l_nouvelle_variable).variable =
449: malloc(sizeof(struct_variable))) == NULL)
450: {
451: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
452: return(d_erreur);
453: }
454:
455: (*(*l_nouvelle_variable).variable) = (*s_variable);
456: pointeur_variable_cree = (*l_nouvelle_variable).variable;
457: }
458: }
459:
460: // Ajout de la variable nouvellement créée à la liste par niveaux.
461: // Le pointeur contenu dans la structure de description du processus indique
462: // toujours le plus haut niveau utilisé.
463:
464: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
465: {
466: // Le niveau courant n'existe pas. Il est créé.
467:
468: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
469: == NULL)
470: {
471: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
472: return(d_erreur);
473: }
474:
475: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
476: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
477: (*l_nouvelle_variable).noeud_pere = NULL;
478: (*l_nouvelle_variable).liste = NULL;
479:
480: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
481:
482: // Ajout de la variable en tête de la liste
483:
484: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
485: {
486: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
487: return(d_erreur);
488: }
489:
490: (*l_nouvel_element).suivant = (*(*s_etat_processus)
491: .l_liste_variables_par_niveau).liste;
492: (*l_nouvel_element).donnee = pointeur_variable_cree;
493: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
494: l_nouvel_element;
495: }
496: else if ((*s_variable).niveau > (*((struct_variable *)
497: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
498: .donnee)).niveau)
499: {
500: // Le niveau courant n'existe pas. Il est créé.
501:
502: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
503: == NULL)
504: {
505: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
506: return(d_erreur);
507: }
508:
509: (*l_nouvelle_variable).suivant = (*s_etat_processus)
510: .l_liste_variables_par_niveau;
511: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
512: .l_liste_variables_par_niveau).precedent;
513: (*l_nouvelle_variable).noeud_pere = NULL;
514: (*l_nouvelle_variable).liste = NULL;
515: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
516: .suivant = l_nouvelle_variable;
517: (*(*s_etat_processus).l_liste_variables_par_niveau)
518: .precedent = l_nouvelle_variable;
519:
520: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
521:
522: // Ajout de la variable en tête de la liste
523:
524: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
525: {
526: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
527: return(d_erreur);
528: }
529:
530: (*l_nouvel_element).suivant = (*(*s_etat_processus)
531: .l_liste_variables_par_niveau).liste;
532: (*l_nouvel_element).donnee = pointeur_variable_cree;
533: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
534: l_nouvel_element;
535: }
536: else if ((*s_variable).niveau <= 1)
537: {
538: // Création d'une variable de niveau 0 ou 1. Il convient de
539: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
540: // regarde la position courante et les deux précédentes.
541:
542: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
543: niveau_acceptable = d_faux;
544:
545: for(i = 0; i <= 2; i++)
546: {
547: if ((*l_variable_candidate).liste == NULL)
548: {
549: continue;
550: }
551:
552: if ((*((struct_variable *) (*(*l_variable_candidate)
553: .liste).donnee)).niveau == (*s_variable).niveau)
554: {
555: niveau_acceptable = d_vrai;
556: break;
557: }
558:
559: l_variable_candidate = (*l_variable_candidate).precedent;
560: }
561:
562: if (niveau_acceptable == d_faux)
563: {
564: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
565: == NULL)
566: {
567: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
568: return(d_erreur);
569: }
570:
571: l_variable_candidate =
572: (*(*s_etat_processus).l_liste_variables_par_niveau)
573: .precedent;
574:
575: // On ne peut créer qu'une variable de niveau supérieur ou égal à
576: // 1 lors de l'exécution normale d'un programme. Les variables
577: // de niveau 0 sont créées à l'initialisation et relèvent du
578: // cas précédent car il n'existe lors de leur création aucun
579: // niveau non nul.
580:
581: BUG((*s_variable).niveau == 0,
582: uprintf("Attempt to create a level-0 variable!\n"));
583:
584: (*l_nouvelle_variable).suivant = l_variable_candidate;
585: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
586: .precedent;
587: (*l_nouvelle_variable).noeud_pere = NULL;
588: (*l_nouvelle_variable).liste = NULL;
589: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
590: (*l_variable_candidate).precedent = l_nouvelle_variable;
591:
592: l_variable_candidate = l_nouvelle_variable;
593: }
594:
595: // Ajout de la variable en tête de la liste l_variable_candidate.
596:
597: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
598: {
599: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
600: return(d_erreur);
601: }
602:
603: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
604: (*l_nouvel_element).donnee = pointeur_variable_cree;
605: (*l_variable_candidate).liste = l_nouvel_element;
606: }
607: else
608: {
609: // Ajout de la variable en tête de la liste
610:
611: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
612: {
613: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
614: return(d_erreur);
615: }
616:
617: (*l_nouvel_element).suivant = (*(*s_etat_processus)
618: .l_liste_variables_par_niveau).liste;
619: (*l_nouvel_element).donnee = pointeur_variable_cree;
620: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
621: l_nouvel_element;
622: }
623:
624: return(d_absence_erreur);
625: }
626:
627:
628: logical1
629: creation_variable(struct_processus *s_etat_processus,
630: struct_variable *s_variable,
631: unsigned char autorisation_creation_variable_statique,
632: unsigned char autorisation_creation_variable_partagee)
633: {
634: if ((*s_etat_processus).mode_execution_programme == 'Y')
635: {
636: (*s_variable).origine = 'P';
637: }
638: else
639: {
640: (*s_variable).origine = 'E';
641: }
642:
643: if ((*s_variable).niveau == 0)
644: {
645: // Un point d'entrée de définition est verrouillé.
646:
647: if ((*s_variable).origine == 'P')
648: {
649: (*s_variable).variable_statique.adresse = 0;
650: (*s_variable).variable_partagee.adresse = 0;
651: }
652: else
653: {
654: (*s_variable).variable_statique.pointeur = NULL;
655: (*s_variable).variable_partagee.pointeur = NULL;
656: }
657:
658: (*s_variable).variable_verrouillee = d_vrai;
659: }
660: else if ((*s_variable).niveau == 1)
661: {
662: // Une variable globale ne peut être statique.
663:
664: if ((*s_variable).origine == 'P')
665: {
666: (*s_variable).variable_statique.adresse = 0;
667: (*s_variable).variable_partagee.adresse = 0;
668: }
669: else
670: {
671: (*s_variable).variable_statique.pointeur = NULL;
672: (*s_variable).variable_partagee.pointeur = NULL;
673: }
674:
675: (*s_variable).variable_verrouillee = d_faux;
676: }
677: else
678: {
679: // 0 -> variable volatile
680: // adresse de création -> variable statique
681:
682: if (autorisation_creation_variable_statique == 'V')
683: {
684: if (autorisation_creation_variable_partagee == 'S')
685: {
686: // On force la création d'une variable partagée
687:
688: if ((*s_variable).origine == 'P')
689: {
690: (*s_variable).variable_statique.adresse = 0;
691: (*s_variable).variable_partagee.adresse =
692: (*s_etat_processus).position_courante;
693: }
694: else
695: {
696: (*s_variable).variable_statique.pointeur = NULL;
697: (*s_variable).variable_partagee.pointeur =
698: (*s_etat_processus).objet_courant;
699: }
700: }
701: else
702: {
703: // On force la création d'une variable volatile
704:
705: if ((*s_variable).origine == 'P')
706: {
707: (*s_variable).variable_statique.adresse = 0;
708: (*s_variable).variable_partagee.adresse = 0;
709: }
710: else
711: {
712: (*s_variable).variable_statique.pointeur = NULL;
713: (*s_variable).variable_partagee.pointeur = NULL;
714: }
715: }
716: }
717: else
718: {
719: // On force la création d'une variable statique.
720:
721: if ((*s_variable).origine == 'P')
722: {
723: (*s_variable).variable_statique.adresse =
724: (*s_etat_processus).position_courante;
725: (*s_variable).variable_partagee.adresse = 0;
726: }
727: else
728: {
729: (*s_variable).variable_statique.pointeur =
730: (*s_etat_processus).objet_courant;
731: (*s_variable).variable_partagee.pointeur = 0;
732: }
733: }
734:
735: (*s_variable).variable_verrouillee = d_faux;
736: }
737:
738: /*
739: * Recherche de la feuille correspondante dans l'arbre des variables.
740: * Si cette feuille n'existe pas, elle est créée.
741: */
742:
743: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
744: {
745: return(d_erreur);
746: }
747:
748: return(d_absence_erreur);
749: }
750:
751:
752: /*
753: ================================================================================
754: Procédure de recherche d'une variable par son nom dans la base
755: ================================================================================
756: Entrée :
757: --------------------------------------------------------------------------------
758: Sortie :
759: --------------------------------------------------------------------------------
760: Effets de bord : néant
761: ================================================================================
762: */
763:
764: logical1
765: recherche_variable(struct_processus *s_etat_processus,
766: unsigned char *nom_variable)
767: {
768: int pointeur;
769:
770: struct_arbre_variables *l_variable_courante;
771: struct_liste_pile_systeme *l_element_courant;
772:
773: unsigned char *ptr;
774:
775: unsigned long niveau_appel;
776:
777: if ((*s_etat_processus).s_arbre_variables == NULL)
778: {
779: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
780: return(d_faux);
781: }
782:
783: l_variable_courante = (*s_etat_processus).s_arbre_variables;
784: ptr = nom_variable;
785:
786: while((*ptr) != d_code_fin_chaine)
787: {
788: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
789:
790: if (pointeur < 0)
791: {
792: // Caractère hors de l'alphabet des variables
793:
794: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
795: return(d_faux);
796: }
797:
798: if ((*l_variable_courante).noeuds[pointeur] == NULL)
799: {
800: // Le chemin de la variable candidate n'existe pas.
801: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
802: return(d_faux);
803: }
804:
805: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
806: ptr++;
807: }
808:
809: if ((*l_variable_courante).feuille != NULL)
810: {
811: // Il existe une pile de variables de même nom. Le sommet de la
812: // pile est la variable de niveau le plus haut.
813:
814: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
815:
816: if (l_element_courant == NULL)
817: {
818: // Problème : la pile système est vide !
819: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
820: return(d_faux);
821: }
822:
823: while((*l_element_courant).retour_definition != 'Y')
824: {
825: l_element_courant = (*l_element_courant).suivant;
826:
827: if (l_element_courant == NULL)
828: {
829: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
830: return(d_faux);
831: }
832: }
833:
834: niveau_appel = (*l_element_courant).niveau_courant;
835:
836: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
837: {
838: // Une variable locale est accessible puisque créée dans la
839: // fonction courante.
840:
841: (*s_etat_processus).pointeur_variable_courante =
842: (*(*l_variable_courante).feuille).variable;
843: (*s_etat_processus).pointeur_feuille_courante =
844: (*l_variable_courante).feuille;
845: return(d_vrai);
846: }
847: else
848: {
849: // Aucune variable locale n'est accessible depuis la fonction.
850: // Dans ce cas, on prend la variable de niveau le plus bas
851: // si ce niveau est inférieur ou égal à 1 (variable globale
852: // ou fonction définie par l'utilisateur). Si le niveau de la
853: // plus ancienne variable est strictement supérieur à 1, il
854: // s'agit d'une variable locale inaccessible.
855:
856: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
857: .niveau <= 1)
858: {
859: (*s_etat_processus).pointeur_variable_courante =
860: (*(*(*l_variable_courante).feuille).precedent).variable;
861: (*s_etat_processus).pointeur_feuille_courante =
862: (*(*l_variable_courante).feuille).precedent;
863:
864: // S'il existe une variable de niveau 0 et une seconde de
865: // niveau 1, la variable de niveau 0 (fonction) est masquée
866: // par celle de niveau 1.
867:
868: if (((*(*(*(*l_variable_courante).feuille).precedent)
869: .variable).niveau == 0) && ((*(*(*(*
870: (*l_variable_courante).feuille).precedent).precedent)
871: .variable).niveau == 1))
872: {
873: (*s_etat_processus).pointeur_variable_courante =
874: (*(*(*(*l_variable_courante).feuille).precedent)
875: .precedent).variable;
876: (*s_etat_processus).pointeur_feuille_courante =
877: (*(*(*l_variable_courante).feuille).precedent)
878: .precedent;
879: }
880:
881: return(d_vrai);
882: }
883: }
884: }
885:
886: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
887: return(d_faux);
888: }
889:
890:
891: logical1
892: recherche_variable_globale(struct_processus *s_etat_processus,
893: unsigned char *nom)
894: {
895: logical1 presence_variable;
896:
897: presence_variable = recherche_variable(s_etat_processus, nom);
898:
899: if (presence_variable == d_vrai)
900: {
901: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
902: {
903: case 0:
904: {
905: // La variable est une définition.
906: presence_variable = d_faux;
907: break;
908: }
909:
910: case 1:
911: {
912: break;
913: }
914:
915: default:
916: {
917: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
918: .precedent).variable).niveau == 1)
919: {
920: (*s_etat_processus).pointeur_feuille_courante =
921: (*(*s_etat_processus).pointeur_feuille_courante)
922: .precedent;
923: (*s_etat_processus).pointeur_variable_courante =
924: (*(*s_etat_processus).pointeur_feuille_courante)
925: .variable;
926: }
927: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
928: .precedent).precedent).variable).niveau == 1)
929: {
930: (*s_etat_processus).pointeur_feuille_courante =
931: (*(*(*s_etat_processus).pointeur_feuille_courante)
932: .precedent).precedent;
933: (*s_etat_processus).pointeur_variable_courante =
934: (*(*s_etat_processus).pointeur_feuille_courante)
935: .variable;
936: }
937: else
938: {
939: presence_variable = d_faux;
940: }
941:
942: break;
943: }
944: }
945: }
946:
947: if (presence_variable == d_vrai)
948: {
949: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
950: {
951: // La variable n'est pas globale, elle est partagée.
952: presence_variable = d_faux;
953: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
954: }
955: }
956:
957: return(presence_variable);
958: }
959:
960:
961: /*
962: ================================================================================
963: Procédure de retrait d'une variable de la base
964: ================================================================================
965: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
966: les globales) ou strictement globale.
967: --------------------------------------------------------------------------------
968: Sortie :
969: --------------------------------------------------------------------------------
970: Effets de bord : néant
971: ================================================================================
972: */
973:
974: logical1
975: retrait_variable(struct_processus *s_etat_processus,
976: unsigned char *nom_variable, unsigned char type)
977: {
978: logical1 erreur;
979:
980: struct_arbre_variables *s_arbre_a_supprimer;
981: struct_arbre_variables *s_arbre_courant;
982: struct_arbre_variables *noeud_courant;
983:
984: struct_liste_chainee *l_element_courant;
985: struct_liste_chainee *l_element_precedent;
986:
987: struct_liste_variables *variable_a_supprimer;
988: struct_liste_variables *variables_par_niveau;
989:
990: unsigned long niveau;
991:
992: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
993: {
994: // Une variable correspondant au nom recherché est accessible.
995:
996: if (type == 'G')
997: {
998: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
999: {
1000: // La variable obtenue est une variable locale. il faut
1001: // s'assurer qu'il existe une variable de niveau 1 de même
1002: // nom sur la feuille.
1003:
1004: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1005: .precedent).variable).niveau <= 1)
1006: {
1007: (*s_etat_processus).pointeur_feuille_courante =
1008: (*(*s_etat_processus).pointeur_feuille_courante)
1009: .precedent;
1010: (*s_etat_processus).pointeur_variable_courante =
1011: (*(*s_etat_processus).pointeur_feuille_courante)
1012: .variable;
1013:
1014: // Si la variable retournée est de niveau 0, on regarde
1015: // un peu plus loin si une variable de niveau 1 existe.
1016:
1017: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1018: .variable).niveau == 0) &&
1019: ((*(*(*(*s_etat_processus)
1020: .pointeur_feuille_courante).precedent).variable)
1021: .niveau == 1))
1022: {
1023: (*s_etat_processus).pointeur_feuille_courante =
1024: (*(*s_etat_processus).pointeur_feuille_courante)
1025: .precedent;
1026: (*s_etat_processus).pointeur_variable_courante =
1027: (*(*s_etat_processus).pointeur_feuille_courante)
1028: .variable;
1029: }
1030: }
1031: else
1032: {
1033: // Aucune variable globale (niveau 1) n'existe.
1034:
1035: erreur = d_erreur;
1036: (*s_etat_processus).erreur_execution =
1037: d_ex_variable_non_definie;
1038: return(erreur);
1039: }
1040: }
1041:
1042: if ((*(*s_etat_processus).pointeur_variable_courante)
1043: .variable_verrouillee == d_vrai)
1044: {
1045: erreur = d_erreur;
1046: (*s_etat_processus).erreur_execution =
1047: d_ex_variable_verrouillee;
1048: return(erreur);
1049: }
1050: }
1051:
1052: // Suppression de la variable de la liste.
1053: // Deux cas peuvent survenir :
1054: // 1/ les pointeurs sur la variable et la variable suivante
1055: // sont identiques et on supprime la variable ainsi que la feuille
1056: // associée ;
1057: // 2/ ces deux pointeurs sont différents et se contente de retirer
1058: // la structure décrivant la variable.
1059:
1060: if ((*s_etat_processus).pointeur_feuille_courante ==
1061: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1062: {
1063: // Cas 1 :
1064: // On retire la variable du noeud en décrémentant le nombre
1065: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1066: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1067: // un nombre non nul de feuilles utilisées (ou la racine des
1068: // variables).
1069:
1070: variable_a_supprimer = (*s_etat_processus)
1071: .pointeur_feuille_courante;
1072: s_arbre_courant = (*variable_a_supprimer).noeud_pere;
1073: noeud_courant = (*variable_a_supprimer).noeud;
1074: (*s_arbre_courant).noeuds[(*noeud_courant).indice_tableau_pere]
1075: = NULL;
1076:
1077: BUG((*s_arbre_courant).noeuds_utilises == 0,
1078: uprintf("Freed node !\n"));
1079: (*s_arbre_courant).noeuds_utilises--;
1080:
1081: while((*s_arbre_courant).noeuds_utilises == 0)
1082: {
1083: s_arbre_a_supprimer = s_arbre_courant;
1084: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1085:
1086: if (s_arbre_courant == NULL)
1087: {
1088: free((*s_arbre_a_supprimer).noeuds);
1089: free(s_arbre_a_supprimer);
1090: break;
1091: }
1092:
1093: // s_arbre_a_supprimer contient la structure de feuille qui
1094: // vient d'être libérée. Il s'agit maintenant
1095: // d'annuler le pointeur dans le tableau noeuds de la structure
1096: // pointée par noeud_pere, soit s_arbre_courant.
1097:
1098: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1099: uprintf("Invalid pointer !\n"));
1100: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1101: .indice_tableau_pere] = NULL;
1102:
1103: free((*s_arbre_a_supprimer).noeuds);
1104: free(s_arbre_a_supprimer);
1105:
1106: BUG((*s_arbre_courant).noeuds_utilises == 0,
1107: uprintf("Freed node !\n"));
1108: (*s_arbre_courant).noeuds_utilises--;
1109: }
1110: }
1111: else
1112: {
1113: // Cas 2 :
1114: // On retire la variable de la liste.
1115:
1116: variable_a_supprimer = (*s_etat_processus)
1117: .pointeur_feuille_courante;
1118:
1119: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1120: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1121: .suivant;
1122: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1123: .precedent = (*(*s_etat_processus)
1124: .pointeur_feuille_courante).precedent;
1125:
1126: // Mise à jour du pointeur dans l'arbre des variables. Cette
1127: // mise à jour n'est nécessaire que dans le cas où la variable
1128: // supprimée est en tête de la liste.
1129:
1130: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
1131: .noeuds[(*(*variable_a_supprimer).noeud)
1132: .indice_tableau_pere])).feuille)
1133: {
1134: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1135: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1136: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
1137: .noeuds[(*(*variable_a_supprimer).noeud)
1138: .indice_tableau_pere])).feuille).suivant;
1139: }
1140:
1141: (*s_etat_processus).pointeur_feuille_courante =
1142: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
1143: (*s_etat_processus).pointeur_variable_courante =
1144: (*(*s_etat_processus).pointeur_feuille_courante).variable;
1145:
1146: noeud_courant = NULL;
1147: }
1148:
1149: // Dans tous les cas, on retire la variable de la liste des variables
1150: // par niveau.
1151:
1152: niveau = (*(*variable_a_supprimer).variable).niveau;
1153: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1154:
1155: if (variables_par_niveau != NULL)
1156: {
1157: do
1158: {
1159: l_element_courant = (*variables_par_niveau).liste;
1160:
1161: if (l_element_courant != NULL)
1162: {
1163: if ((*((struct_variable *) (*l_element_courant).donnee))
1164: .niveau == niveau)
1165: {
1166: // On parcourt le bon niveau.
1167:
1168: l_element_precedent = NULL;
1169:
1170: while(l_element_courant != NULL)
1171: {
1172: // Tant que l_element_courant est non nul, il reste
1173: // des variables à explorer dans le niveau courant.
1174:
1175: if ((*l_element_courant).donnee ==
1176: (void *) (*variable_a_supprimer).variable)
1177: {
1178: // On a trouvé la variable à supprimer.
1179:
1180: if (l_element_precedent == NULL)
1181: {
1182: (*variables_par_niveau).liste =
1183: (*l_element_courant).suivant;
1184: }
1185: else
1186: {
1187: (*l_element_precedent).suivant =
1188: (*l_element_courant).suivant;
1189: }
1190:
1191: free(l_element_courant);
1192: break;
1193: }
1194:
1195: l_element_precedent = l_element_courant;
1196: l_element_courant = (*l_element_courant).suivant;
1197: }
1198: }
1199: }
1200:
1201: variables_par_niveau = (*variables_par_niveau).suivant;
1202:
1203: } while(variables_par_niveau != (*s_etat_processus)
1204: .l_liste_variables_par_niveau);
1205: }
1206:
1207: // Puis on libère le contenu de la variable.
1208:
1209: free((*(*variable_a_supprimer).variable).nom);
1210: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1211: free((*variable_a_supprimer).variable);
1212: free(variable_a_supprimer);
1213:
1214: erreur = d_absence_erreur;
1215:
1216: if (noeud_courant != NULL)
1217: {
1218: free((*noeud_courant).noeuds);
1219: free(noeud_courant);
1220: }
1221: }
1222: else
1223: {
1224: // Aucune variable n'est accessible depuis le point courant du
1225: // programme.
1226:
1227: erreur = d_erreur;
1228: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1229: }
1230:
1231: return(erreur);
1232: }
1233:
1234:
1235: /*
1236: ================================================================================
1237: Procédure de retrait des variables de niveau strictement supérieur au
1238: niveau courant
1239: ================================================================================
1240: Entrée :
1241: --------------------------------------------------------------------------------
1242: Sortie :
1243: --------------------------------------------------------------------------------
1244: Effets de bord : néant
1245: ================================================================================
1246: */
1247:
1248: logical1
1249: retrait_variable_par_niveau(struct_processus *s_etat_processus)
1250: {
1251: struct_liste_variables *l_element_a_supprimer;
1252:
1253: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1254: // La tête de la pile contient toujours les variables de plus haut niveau
1255: // créées.
1256:
1257: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1258: {
1259: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1260: {
1261: // Si le niveau ne contient aucune variable, on le détruit.
1262: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1263: // faire.
1264: }
1265: else
1266: {
1267: // Le niveau contient des variables.
1268:
1269: if ((*((struct_variable *) (*(*(*s_etat_processus)
1270: .l_liste_variables_par_niveau).liste).donnee)).niveau
1271: <= (*s_etat_processus).niveau_courant)
1272: {
1273: // On a retiré de l'arbre des variables toutes les
1274: // variables de niveau strictement supérieur au niveau
1275: // courant.
1276:
1277: break;
1278: }
1279:
1280: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1281: != NULL)
1282: {
1283: // Sauvegarde des variables statiques.
1284:
1285: if ((*((struct_variable *) (*(*(*s_etat_processus)
1286: .l_liste_variables_par_niveau).liste).donnee)).origine
1287: == 'P')
1288: {
1289: if ((*((struct_variable *) (*(*(*s_etat_processus)
1290: .l_liste_variables_par_niveau).liste).donnee))
1291: .variable_statique.adresse != 0)
1292: {
1293: if (recherche_variable_statique(s_etat_processus,
1294: (*((struct_variable *) (*(*(*s_etat_processus)
1295: .l_liste_variables_par_niveau).liste).donnee))
1296: .nom, (*((struct_variable *)
1297: (*(*(*s_etat_processus)
1298: .l_liste_variables_par_niveau).liste).donnee))
1299: .variable_statique, ((*s_etat_processus)
1300: .mode_execution_programme
1301: == 'Y') ? 'P' : 'E') == d_vrai)
1302: {
1303: (*s_etat_processus).s_liste_variables_statiques
1304: [(*s_etat_processus)
1305: .position_variable_statique_courante]
1306: .objet = (*((struct_variable *)
1307: (*(*(*s_etat_processus)
1308: .l_liste_variables_par_niveau).liste)
1309: .donnee)).objet;
1310: }
1311: else
1312: {
1313: (*s_etat_processus).erreur_systeme =
1314: d_es_variable_introuvable;
1315: }
1316:
1317: (*((struct_variable *) (*(*(*s_etat_processus)
1318: .l_liste_variables_par_niveau).liste).donnee))
1319: .objet = NULL;
1320: }
1321: }
1322: else
1323: {
1324: if ((*((struct_variable *) (*(*(*s_etat_processus)
1325: .l_liste_variables_par_niveau).liste).donnee))
1326: .variable_statique.pointeur != NULL)
1327: {
1328: /*
1329: * Gestion des variables statiques
1330: */
1331:
1332: if (recherche_variable_statique(s_etat_processus,
1333: (*((struct_variable *) (*(*(*s_etat_processus)
1334: .l_liste_variables_par_niveau).liste).donnee))
1335: .nom, (*((struct_variable *)
1336: (*(*(*s_etat_processus)
1337: .l_liste_variables_par_niveau).liste).donnee))
1338: .variable_statique, ((*s_etat_processus)
1339: .mode_execution_programme
1340: == 'Y') ? 'P' : 'E') == d_vrai)
1341: {
1342: (*s_etat_processus).s_liste_variables_statiques
1343: [(*s_etat_processus)
1344: .position_variable_statique_courante]
1345: .objet = (*((struct_variable *)
1346: (*(*(*s_etat_processus)
1347: .l_liste_variables_par_niveau).liste)
1348: .donnee)).objet;
1349: }
1350: else
1351: {
1352: (*s_etat_processus).erreur_systeme =
1353: d_es_variable_introuvable;
1354: return(d_erreur);
1355: }
1356:
1357: (*((struct_variable *) (*(*(*s_etat_processus)
1358: .l_liste_variables_par_niveau).liste).donnee))
1359: .objet = NULL;
1360: }
1361: }
1362:
1363: if (retrait_variable(s_etat_processus,
1364: (*((struct_variable *) (*(*(*s_etat_processus)
1365: .l_liste_variables_par_niveau).liste).donnee)).nom,
1366: 'L') == d_erreur)
1367: {
1368: return(d_erreur);
1369: }
1370: }
1371: }
1372:
1373: // On retire l'élément de la liste doublement chaînée et circulaire.
1374:
1375: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1376: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1377: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1378: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1379:
1380: l_element_a_supprimer = (*s_etat_processus)
1381: .l_liste_variables_par_niveau;
1382: (*s_etat_processus).l_liste_variables_par_niveau =
1383: (*l_element_a_supprimer).suivant;
1384: free(l_element_a_supprimer);
1385: }
1386:
1387: return(d_absence_erreur);
1388: }
1389:
1390:
1391: /*
1392: ================================================================================
1393: Procédure de retrait des toutes les variables locales et globales
1394: ================================================================================
1395: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1396: de niveau 0)
1397: --------------------------------------------------------------------------------
1398: Sortie :
1399: --------------------------------------------------------------------------------
1400: Effets de bord : néant
1401: ================================================================================
1402: */
1403:
1404: void
1405: liberation_arbre_variables(struct_processus *s_etat_processus,
1406: struct_arbre_variables *arbre, logical1 retrait_definitions)
1407: {
1408: int i;
1409:
1410: struct_liste_chainee *l_element_courant_liste;
1411: struct_liste_chainee *l_element_suivant_liste;
1412:
1413: struct_liste_variables *l_element_courant;
1414: struct_liste_variables *l_element_suivant;
1415:
1416: // Libération de l'arbre des variables. Le contenu des variables n'est
1417: // pas détruit par cette opération, il sera détruit lors de la libération
1418: // de la liste des variables par niveau.
1419:
1420: l_element_courant = (*arbre).feuille;
1421:
1422: if (l_element_courant != NULL)
1423: {
1424: do
1425: {
1426: l_element_suivant = (*l_element_courant).suivant;
1427: free(l_element_courant);
1428: l_element_courant = l_element_suivant;
1429: } while(l_element_courant != (*arbre).feuille);
1430: }
1431:
1432: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1433: {
1434: if ((*arbre).noeuds[i] != NULL)
1435: {
1436: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1437: retrait_definitions);
1438: }
1439: }
1440:
1441: // Suppression de la liste des variables par niveau.
1442:
1443: if (arbre == (*s_etat_processus).s_arbre_variables)
1444: {
1445: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1446:
1447: if (l_element_courant != NULL)
1448: {
1449: do
1450: {
1451: l_element_courant_liste = (*l_element_courant).liste;
1452:
1453: while(l_element_courant_liste != NULL)
1454: {
1455: if ((retrait_definitions == d_vrai) ||
1456: ((*((struct_variable *) (*l_element_courant_liste)
1457: .donnee)).niveau >= 1))
1458: {
1459: liberation(s_etat_processus, (*((struct_variable *)
1460: (*l_element_courant_liste).donnee)).objet);
1461: free((*((struct_variable *) (*l_element_courant_liste)
1462: .donnee)).nom);
1463: free((*l_element_courant_liste).donnee);
1464: }
1465:
1466: l_element_suivant_liste =
1467: (*l_element_courant_liste).suivant;
1468: free(l_element_courant_liste);
1469: l_element_courant_liste = l_element_suivant_liste;
1470: }
1471:
1472: l_element_suivant = (*l_element_courant).suivant;
1473: free(l_element_courant);
1474: l_element_courant = l_element_suivant;
1475: } while(l_element_courant != (*s_etat_processus)
1476: .l_liste_variables_par_niveau);
1477: }
1478: }
1479:
1480: free((*arbre).noeuds);
1481: free(arbre);
1482:
1483: return;
1484: }
1485:
1486:
1487: /*
1488: ================================================================================
1489: Procédure renvoyant les variables dans un tableau
1490: ================================================================================
1491: Entrée :
1492: --------------------------------------------------------------------------------
1493: Sortie :
1494: --------------------------------------------------------------------------------
1495: Effets de bord : néant
1496: ================================================================================
1497: */
1498:
1499: int
1500: nombre_variables(struct_processus *s_etat_processus,
1501: struct_arbre_variables *l_element_courant)
1502: {
1503: int i;
1504: int n;
1505:
1506: struct_liste_variables *l_variable;
1507:
1508: n = 0;
1509:
1510: if ((*l_element_courant).feuille != NULL)
1511: {
1512: l_variable = (*l_element_courant).feuille;
1513:
1514: do
1515: {
1516: n++;
1517: l_variable = (*l_variable).suivant;
1518: } while(l_variable != (*l_element_courant).feuille);
1519: }
1520:
1521: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1522: {
1523: if ((*l_element_courant).noeuds[i] != NULL)
1524: {
1525: n += nombre_variables(s_etat_processus,
1526: (*l_element_courant).noeuds[i]);
1527: }
1528: }
1529:
1530: return(n);
1531: }
1532:
1533: int
1534: liste_variables(struct_processus *s_etat_processus,
1535: struct_tableau_variables *tableau, int position,
1536: struct_arbre_variables *l_element_courant)
1537: {
1538: int i;
1539:
1540: struct_liste_variables *l_variable;
1541:
1542: if ((*l_element_courant).feuille != NULL)
1543: {
1544: l_variable = (*l_element_courant).feuille;
1545:
1546: do
1547: {
1548: tableau[position].origine = (*(*l_variable).variable).origine;
1549: tableau[position].nom = (*(*l_variable).variable).nom;
1550: tableau[position].niveau = (*(*l_variable).variable).niveau;
1551: tableau[position].objet = (*(*l_variable).variable).objet;
1552: tableau[position].variable_verrouillee =
1553: (*(*l_variable).variable).variable_verrouillee;
1554: tableau[position].variable_statique =
1555: (*(*l_variable).variable).variable_statique;
1556: tableau[position].variable_partagee =
1557: (*(*l_variable).variable).variable_partagee;
1558:
1559: position++;
1560: l_variable = (*l_variable).suivant;
1561: } while(l_variable != (*l_element_courant).feuille);
1562: }
1563:
1564: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1565: {
1566: if ((*l_element_courant).noeuds[i] != NULL)
1567: {
1568: position = liste_variables(s_etat_processus,
1569: tableau, position, (*l_element_courant).noeuds[i]);
1570: }
1571: }
1572:
1573: return(position);
1574: }
1575:
1576: /*
1577: ================================================================================
1578: Procédure de copie de l'arbre des variables
1579: ================================================================================
1580: Entrée :
1581: --------------------------------------------------------------------------------
1582: Sortie :
1583: --------------------------------------------------------------------------------
1584: Effets de bord : néant
1585: ================================================================================
1586: */
1587:
1588: struct_arbre_variables *
1589: copie_arbre_variables(struct_processus *s_etat_processus)
1590: {
1591: // Les définitions sont partagées entre tous les threads et ne sont pas
1592: // copiées.
1593: //
1594: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1595: // variables locales étant masquées par le processus de création de thread
1596: // ou de processus, elles sont inaccessibles.
1597:
1598: BUG(1, uprintf("Oops !\n"));
1599:
1600: return(d_absence_erreur);
1601: }
1602:
1603:
1604: /*
1605: ================================================================================
1606: Procédure d'initialisation de la table de correspondance des variables
1607: ================================================================================
1608: Entrée :
1609: --------------------------------------------------------------------------------
1610: Sortie :
1611: --------------------------------------------------------------------------------
1612: Effets de bord : néant
1613: ================================================================================
1614: */
1615:
1616: /*
1617: * Caractères autorisés dans les instructions
1618: *
1619: * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1620: * a b c d e f g h i j k l m n o p q r s t u v w x y z
1621: * _
1622: * 1 2 3 4 5 6 7 8 9 0
1623: */
1624:
1625: void
1626: initialisation_variables(struct_processus *s_etat_processus)
1627: {
1628: int decalage;
1629: int i;
1630: int longueur_tableau;
1631:
1632: unsigned char caractere;
1633:
1634: // Récupération de la longueur d'un unsigned char
1635:
1636: longueur_tableau = 1;
1637: decalage = 0;
1638: caractere = 1;
1639:
1640: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
1641: {
1642: decalage++;
1643: longueur_tableau *= 2;
1644: }
1645:
1646: if (((*s_etat_processus).pointeurs_caracteres_variables =
1647: malloc(longueur_tableau * sizeof(int))) == NULL)
1648: {
1649: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1650: return;
1651: }
1652:
1653: for(i = 0; i < longueur_tableau; i++)
1654: {
1655: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
1656: }
1657:
1658: (*s_etat_processus).nombre_caracteres_variables = 0;
1659:
1660: #define DECLARATION_CARACTERE(c) \
1661: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
1662: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
1663:
1664: DECLARATION_CARACTERE('A');
1665: DECLARATION_CARACTERE('B');
1666: DECLARATION_CARACTERE('C');
1667: DECLARATION_CARACTERE('D');
1668: DECLARATION_CARACTERE('E');
1669: DECLARATION_CARACTERE('F');
1670: DECLARATION_CARACTERE('G');
1671: DECLARATION_CARACTERE('H');
1672: DECLARATION_CARACTERE('I');
1673: DECLARATION_CARACTERE('J');
1674: DECLARATION_CARACTERE('K');
1675: DECLARATION_CARACTERE('L');
1676: DECLARATION_CARACTERE('M');
1677: DECLARATION_CARACTERE('N');
1678: DECLARATION_CARACTERE('O');
1679: DECLARATION_CARACTERE('P');
1680: DECLARATION_CARACTERE('Q');
1681: DECLARATION_CARACTERE('R');
1682: DECLARATION_CARACTERE('S');
1683: DECLARATION_CARACTERE('T');
1684: DECLARATION_CARACTERE('U');
1685: DECLARATION_CARACTERE('V');
1686: DECLARATION_CARACTERE('W');
1687: DECLARATION_CARACTERE('X');
1688: DECLARATION_CARACTERE('Y');
1689: DECLARATION_CARACTERE('Z');
1690:
1691: DECLARATION_CARACTERE('a');
1692: DECLARATION_CARACTERE('b');
1693: DECLARATION_CARACTERE('c');
1694: DECLARATION_CARACTERE('d');
1695: DECLARATION_CARACTERE('e');
1696: DECLARATION_CARACTERE('f');
1697: DECLARATION_CARACTERE('g');
1698: DECLARATION_CARACTERE('h');
1699: DECLARATION_CARACTERE('i');
1700: DECLARATION_CARACTERE('j');
1701: DECLARATION_CARACTERE('k');
1702: DECLARATION_CARACTERE('l');
1703: DECLARATION_CARACTERE('m');
1704: DECLARATION_CARACTERE('n');
1705: DECLARATION_CARACTERE('o');
1706: DECLARATION_CARACTERE('p');
1707: DECLARATION_CARACTERE('q');
1708: DECLARATION_CARACTERE('r');
1709: DECLARATION_CARACTERE('s');
1710: DECLARATION_CARACTERE('t');
1711: DECLARATION_CARACTERE('u');
1712: DECLARATION_CARACTERE('v');
1713: DECLARATION_CARACTERE('w');
1714: DECLARATION_CARACTERE('x');
1715: DECLARATION_CARACTERE('y');
1716: DECLARATION_CARACTERE('z');
1717:
1718: DECLARATION_CARACTERE('_');
1719:
1720: DECLARATION_CARACTERE('1');
1721: DECLARATION_CARACTERE('2');
1722: DECLARATION_CARACTERE('3');
1723: DECLARATION_CARACTERE('4');
1724: DECLARATION_CARACTERE('5');
1725: DECLARATION_CARACTERE('6');
1726: DECLARATION_CARACTERE('7');
1727: DECLARATION_CARACTERE('8');
1728: DECLARATION_CARACTERE('9');
1729: DECLARATION_CARACTERE('0');
1730: #undef DECLARATION_CARACTERE
1731:
1732: return;
1733: }
1734:
1735: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>