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