Annotation of rpl/src/gestion_variables.c, revision 1.61
1.1 bertrand 1: /*
2: ================================================================================
1.57 bertrand 3: RPL/2 (R) version 4.1.11
1.50 bertrand 4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1 bertrand 5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
1.14 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
1.33 bertrand 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:
1.38 bertrand 49: printf("=========================================================="
50: "======================\n");
1.33 bertrand 51: printf(" Liste des variables par niveaux\n");
1.38 bertrand 52: printf("=========================================================="
53: "======================\n");
1.33 bertrand 54:
1.34 bertrand 55: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
56: {
1.38 bertrand 57: printf("=========================================================="
58: "======================\n");
1.34 bertrand 59: return;
60: }
61:
1.33 bertrand 62: printf("Backward\n");
63: l = (*s_etat_processus).l_liste_variables_par_niveau;
64: c = 0;
65: fin = d_faux;
66:
67: do
68: {
69: l = l->precedent;
70: e = l->liste;
71:
72: while(e != NULL)
73: {
1.38 bertrand 74: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
75: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
1.33 bertrand 76: e = e->suivant;
77: c++;
78: if (c > 100)
79: {
80: fin = d_vrai;
81: break;
82: }
83: }
84:
85: printf("\n");
86:
87: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
88:
89: printf("Forward\n");
90: l = (*s_etat_processus).l_liste_variables_par_niveau;
91: c = 0;
92:
93: do
94: {
95: e = l->liste;
96:
97: while(e != NULL)
98: {
1.38 bertrand 99: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
100: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
1.33 bertrand 101: e = e->suivant;
102: c++;
103: if (c > 100) exit(0);
104: }
105:
106: printf("\n");
107:
108: l = l->suivant;
109: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
110:
1.38 bertrand 111: printf("=========================================================="
112: "======================\n");
1.33 bertrand 113:
114: if (fin == d_vrai) exit(0);
115:
116: return;
117: }
118:
119: static void
120: liste_variables_tas(struct_processus *s_etat_processus,
121: struct_arbre_variables *arbre)
122: {
123: int c;
124: int i;
125:
126: logical1 fin;
127:
128: struct_liste_variables *l;
129:
130: fin = d_faux;
131:
1.34 bertrand 132: if (arbre == NULL)
133: {
134: return;
135: }
136:
137: printf(">>> Position : %d\n",
138: (*arbre).indice_tableau_pere);
139: printf(">>> Nombre de noeuds utilisés : %u\n",
140: (*arbre).noeuds_utilises);
141: printf(">>> Noeuds fils : ");
142:
143: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
144: {
145: if ((*arbre).noeuds[i] != NULL)
146: {
147: printf("%d ", i);
148: }
149: }
150:
151: printf("\b\n");
152:
1.33 bertrand 153: if ((*arbre).feuille != NULL)
154: {
1.34 bertrand 155: printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
1.33 bertrand 156:
157: printf(" Backward\n");
158:
159: l = (*arbre).feuille;
160: c = 0;
161: fin = d_faux;
162:
163: do
164: {
165: l = l->precedent;
166: c++;
167: if (c > 100)
168: {
169: fin = d_vrai;
170: break;
171: }
172: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
173: l->variable->niveau);
174: } while((*arbre).feuille != l);
175:
176: printf(" Forward\n");
177:
178: l = (*arbre).feuille;
179: c = 0;
180:
181: do
182: {
183: c++;
184: if (c > 100) exit(0);
185: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
186: l->variable->niveau);
187: l = l->suivant;
188: } while((*arbre).feuille != l);
189: }
190:
1.38 bertrand 191: printf("----------------------------------------------------------"
192: "----------------------\n");
1.34 bertrand 193:
1.33 bertrand 194: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
195: {
196: if ((*arbre).noeuds[i] != NULL)
197: {
1.34 bertrand 198:
1.33 bertrand 199: liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
200: }
201: }
202:
203: if (fin == d_vrai) exit(0);
204:
205: return;
206: }
207:
208:
209: static void
210: liste_variables_par_feuilles(struct_processus *s_etat_processus)
211: {
1.38 bertrand 212: printf("=========================================================="
213: "======================\n");
1.33 bertrand 214: printf(" Liste des variables sur le tas\n");
1.38 bertrand 215: printf("=========================================================="
216: "======================\n");
1.33 bertrand 217:
218: liste_variables_tas(s_etat_processus,
219: (*s_etat_processus).s_arbre_variables);
220:
1.38 bertrand 221: printf("=========================================================="
222: "======================\n");
1.33 bertrand 223:
224: return;
225: }
226:
227:
228: /*
229: ================================================================================
1.40 bertrand 230: Routine de gestion du cache mémoire sur l'arbre des variables
231: ================================================================================
232: Entrée :
233: --------------------------------------------------------------------------------
234: Sortie :
235: --------------------------------------------------------------------------------
236: Effets de bords : néant
237: ================================================================================
238: */
239:
1.61 ! bertrand 240: struct_arbre_variables *
1.40 bertrand 241: allocation_noeud(struct_processus *s_etat_processus)
242: {
243: struct_arbre_variables *objet;
244:
245: if ((*s_etat_processus).pointeur_variables_noeud > 0)
246: {
247: objet = (*s_etat_processus).variables_noeud
248: [--(*s_etat_processus).pointeur_variables_noeud];
249: }
250: else
251: {
252: objet = malloc(sizeof(struct_arbre_variables));
253: }
254:
255: return(objet);
256: }
257:
258: static inline void
259: liberation_noeud(struct_processus *s_etat_processus,
260: struct_arbre_variables *objet)
261: {
262: if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE)
263: {
264: (*s_etat_processus).variables_noeud
265: [(*s_etat_processus).pointeur_variables_noeud++] = objet;
266: }
267: else
268: {
269: free(objet);
270: }
271:
272: return;
273: }
274:
1.61 ! bertrand 275: struct_arbre_variables **
1.40 bertrand 276: allocation_tableau_noeuds(struct_processus *s_etat_processus)
277: {
278: struct_arbre_variables **objet;
279:
280: if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0)
281: {
282: objet = (*s_etat_processus).variables_tableau_noeuds
283: [--(*s_etat_processus).pointeur_variables_tableau_noeuds];
284: }
285: else
286: {
287: objet = malloc((*s_etat_processus).nombre_caracteres_variables
288: * sizeof(struct_arbre_variables *));
289: }
290:
291: return(objet);
292: }
293:
294: static inline void
295: liberation_tableau_noeuds(struct_processus *s_etat_processus,
296: struct_arbre_variables **objet)
297: {
298: if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
299: {
300: (*s_etat_processus).variables_tableau_noeuds
301: [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
302: objet;
303: }
304: else
305: {
306: free(objet);
307: }
308:
309: return;
310: }
311:
312: static inline struct_liste_variables *
313: allocation_feuille(struct_processus *s_etat_processus)
314: {
315: struct_liste_variables *objet;
316:
317: if ((*s_etat_processus).pointeur_variables_feuille > 0)
318: {
319: objet = (*s_etat_processus).variables_feuille
320: [--(*s_etat_processus).pointeur_variables_feuille];
321: }
322: else
323: {
324: objet = malloc(sizeof(struct_liste_variables));
325: }
326:
327: return(objet);
328: }
329:
330: static inline void
331: liberation_feuille(struct_processus *s_etat_processus,
332: struct_liste_variables *objet)
333: {
334: if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
335: {
336: (*s_etat_processus).variables_feuille
337: [(*s_etat_processus).pointeur_variables_feuille++] = objet;
338: }
339: else
340: {
341: free(objet);
342: }
343:
344: return;
345: }
346:
347: static inline struct_variable *
348: allocation_variable(struct_processus *s_etat_processus)
349: {
350: struct_variable *objet;
351:
352: if ((*s_etat_processus).pointeur_variables_variable > 0)
353: {
354: objet = (*s_etat_processus).variables_variable
355: [--(*s_etat_processus).pointeur_variables_variable];
356: }
357: else
358: {
359: objet = malloc(sizeof(struct_variable));
360: }
361:
362: return(objet);
363: }
364:
365: static inline void
366: liberation_variable(struct_processus *s_etat_processus,
367: struct_variable *objet)
368: {
369: if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
370: {
371: (*s_etat_processus).variables_variable
372: [(*s_etat_processus).pointeur_variables_variable++] = objet;
373: }
374: else
375: {
376: free(objet);
377: }
378:
379: return;
380: }
381:
382:
383: /*
384: ================================================================================
1.1 bertrand 385: Routine de création d'une nouvelle variable
1.33 bertrand 386: ================================================================================
387: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
388: dans le cas 'v', la variable est volatile.
389: dans le cas 's', elle est statique.
390: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
391: dans le cas 'p', la variable est privée.
392: dans le cas 's', elle est partagée.
1.1 bertrand 393: --------------------------------------------------------------------------------
394: Sortie :
395: --------------------------------------------------------------------------------
396: Effets de bords : néant
397: ================================================================================
398: */
399:
1.25 bertrand 400: static logical1
401: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1 bertrand 402: {
1.25 bertrand 403: int i;
404:
1.33 bertrand 405: logical1 niveau_acceptable;
406:
1.25 bertrand 407: struct_liste_variables *l_nouvelle_variable;
408: struct_liste_variables *l_variable_candidate;
1.33 bertrand 409:
1.28 bertrand 410: struct_arbre_variables *l_variable_courante;
411: struct_arbre_variables *l_variable_precedente;
1.1 bertrand 412:
1.25 bertrand 413: struct_liste_chainee *l_nouvel_element;
1.1 bertrand 414:
1.25 bertrand 415: unsigned char *ptr;
1.1 bertrand 416:
1.31 bertrand 417: void *pointeur_variable_cree;
418:
1.25 bertrand 419: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 420: {
1.25 bertrand 421: if (((*s_etat_processus).s_arbre_variables =
1.40 bertrand 422: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 423: {
424: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
425: return(d_erreur);
426: }
427:
428: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
1.58 bertrand 429: (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL;
1.25 bertrand 430: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31 bertrand 431: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28 bertrand 432: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1 bertrand 433:
1.30 bertrand 434: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.60 bertrand 435: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.1 bertrand 436: {
1.25 bertrand 437: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
438: return(d_erreur);
439: }
440:
441: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
442: {
1.28 bertrand 443: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25 bertrand 444: }
445: }
446:
1.28 bertrand 447: l_variable_precedente = NULL;
1.25 bertrand 448: l_variable_courante = (*s_etat_processus).s_arbre_variables;
449: ptr = (*s_variable).nom;
450:
451: while((*ptr) != d_code_fin_chaine)
452: {
453: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
1.40 bertrand 454: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
1.25 bertrand 455: *ptr));
456:
1.28 bertrand 457: if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 458: .pointeurs_caracteres_variables[*ptr]] == NULL)
459: {
1.31 bertrand 460: // Le noeud n'existe pas encore, on le crée et on le marque
461: // comme utilisé dans la structure parente.
1.25 bertrand 462:
1.28 bertrand 463: if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 464: .pointeurs_caracteres_variables[*ptr]] =
1.40 bertrand 465: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 466: {
467: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
468: return(d_erreur);
469: }
470:
1.28 bertrand 471: (*l_variable_courante).noeuds_utilises++;
1.31 bertrand 472:
473: // La feuille est par défaut vide et aucun élément du tableau noeuds
474: // (les branches qui peuvent être issues de ce nouveau noeud)
475: // n'est encore utilisée.
476:
1.28 bertrand 477: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 478: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28 bertrand 479: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.58 bertrand 480: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
481: = NULL;
482: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 483: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31 bertrand 484:
485: // Le champ noeud_pere de la structure créée pointe sur
486: // la structure parente et l'indice tableau_pere correspond à la
487: // position réelle dans le tableau noeuds[] de la structure parente
488: // du noeud courant. Cette valeur sera utilisée lors de la
489: // destruction du noeud pour annuler le pointeur contenu dans
490: // le tableau noeuds[] de la structure parente.
491:
1.28 bertrand 492: (*(*l_variable_courante).noeuds[(*s_etat_processus)
493: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31 bertrand 494: l_variable_courante;
495: (*(*l_variable_courante).noeuds[(*s_etat_processus)
496: .pointeurs_caracteres_variables[*ptr]])
497: .indice_tableau_pere = (*s_etat_processus)
498: .pointeurs_caracteres_variables[*ptr];
499:
500: // Allocation du tableau noeuds[] et initialisation à zéro de
501: // tous les pointeurs.
1.25 bertrand 502:
1.28 bertrand 503: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
504: .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.40 bertrand 505: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.25 bertrand 506: {
507: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
508: return(d_erreur);
509: }
510:
511: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
512: {
1.28 bertrand 513: (*(*l_variable_courante).noeuds[(*s_etat_processus)
514: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
515: = NULL;
1.25 bertrand 516: }
517: }
518:
1.28 bertrand 519: l_variable_precedente = l_variable_courante;
520: l_variable_courante = (*l_variable_courante).noeuds
1.25 bertrand 521: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
522: ptr++;
523: }
524:
525: if ((*l_variable_courante).feuille == NULL)
526: {
527: // Aucune variable de même nom préexiste. On alloue le premier
528: // élément de la liste doublement chaînée contenant toutes les
529: // variables de même nom. Cette liste boucle en premier lieu sur
530: // elle-même.
531:
1.40 bertrand 532: if (((*l_variable_courante).feuille = allocation_feuille(
533: s_etat_processus)) == NULL)
1.25 bertrand 534: {
535: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
536: return(d_erreur);
537: }
538:
1.34 bertrand 539: (*l_variable_courante).noeuds_utilises++;
540:
1.25 bertrand 541: (*(*l_variable_courante).feuille).suivant =
542: (*l_variable_courante).feuille;
543: (*(*l_variable_courante).feuille).precedent =
544: (*l_variable_courante).feuille;
1.28 bertrand 545: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32 bertrand 546: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25 bertrand 547:
548: // Allocation de la variable sur l'élément de la liste.
549:
550: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 551: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 552: {
553: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
554: return(d_erreur);
555: }
556:
557: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
558: (*s_variable);
1.31 bertrand 559: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25 bertrand 560: }
561: else
562: {
1.40 bertrand 563: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.28 bertrand 564: == NULL)
565: {
566: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
567: return(d_erreur);
568: }
569:
1.25 bertrand 570: if ((*s_variable).niveau > 1)
571: {
572: // Cas d'une variable locale
573:
574: // Si le niveau de la dernière variable de même nom est
575: // supérieur au niveau de la variable locale que l'on veut
576: // enregistrer dans la liste, cette liste est incohérente.
577:
578: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
579: (*s_variable).niveau,
1.40 bertrand 580: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 581:
582: // On ajoute la variable à la liste existante.
583:
584: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
585: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
586: .precedent;
1.28 bertrand 587: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 588: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 589: (*(*(*l_variable_courante).feuille).precedent).suivant =
590: l_nouvelle_variable;
591: (*(*l_variable_courante).feuille).precedent =
592: l_nouvelle_variable;
593: (*l_variable_courante).feuille = l_nouvelle_variable;
594:
595: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 596: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 597: {
598: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
599: return(d_erreur);
600: }
601:
602: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
603: = (*s_variable);
1.31 bertrand 604: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1 bertrand 605: }
606: else
607: {
1.25 bertrand 608: // Cas d'une variable globale (niveau 0 [définitions] ou 1
609: // [variables globales])
610:
611: l_variable_candidate = (*l_variable_courante).feuille;
612:
613: do
614: {
615: // S'il y a déjà une variable de même niveau, la pile
616: // est incohérente.
617:
618: BUG((*(*l_variable_candidate).variable).niveau ==
619: (*s_variable).niveau,
1.40 bertrand 620: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 621:
622: l_variable_candidate = (*l_variable_candidate).precedent;
623: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
624: ((*(*l_variable_candidate).variable).niveau <= 1));
625:
1.34 bertrand 626: BUG((*s_variable).niveau == 0,
627: uprintf("Attempt to create a level-0 variable!\n"));
628:
1.25 bertrand 629: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
630: .niveau > 1)
631: {
1.34 bertrand 632: // La variable précédente est de niveau strictement supérieur
633: // à 1. Il ne peut donc y avoir aucune variable de niveau
634: // inférieur ou égal à 1 puisque la boucle est triée.
635: // On insère donc directement la variable en queue.
1.25 bertrand 636: }
637: else
1.1 bertrand 638: {
1.34 bertrand 639: // Le niveau de la variable précédente dans la boucle est
640: // inférieur ou égal à 1.
1.25 bertrand 641: l_variable_candidate = (*(*l_variable_courante).feuille)
642: .precedent;
643: }
644:
645: (*l_nouvelle_variable).suivant = l_variable_candidate;
646: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
647: .precedent;
1.28 bertrand 648: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 649: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 650: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
651: (*l_variable_candidate).precedent = l_nouvelle_variable;
652:
1.34 bertrand 653: // Si la variable suivant la variable que l'on vient d'insérer
654: // dans la boucle est de niveau 0, la variable insérée est par
655: // construction de niveau 1 et il convient de modifier le
656: // pointeur de feuille pointant sur l'élément de plus haut niveau
657: // de la boucle.
658:
659: if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
660: {
661: (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
662: }
663:
1.25 bertrand 664: if (((*l_nouvelle_variable).variable =
1.40 bertrand 665: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 666: {
667: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
668: return(d_erreur);
669: }
670:
671: (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31 bertrand 672: pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1 bertrand 673: }
1.25 bertrand 674: }
675:
676: // Ajout de la variable nouvellement créée à la liste par niveaux.
677: // Le pointeur contenu dans la structure de description du processus indique
678: // toujours le plus haut niveau utilisé.
679:
680: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
681: {
682: // Le niveau courant n'existe pas. Il est créé.
683:
1.40 bertrand 684: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 685: == NULL)
686: {
687: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
688: return(d_erreur);
689: }
690:
691: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
692: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28 bertrand 693: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 694: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 695:
696: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 697:
698: // Ajout de la variable en tête de la liste
699:
1.40 bertrand 700: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 701: {
702: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
703: return(d_erreur);
704: }
705:
706: (*l_nouvel_element).suivant = (*(*s_etat_processus)
707: .l_liste_variables_par_niveau).liste;
708: (*l_nouvel_element).donnee = pointeur_variable_cree;
709: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
710: l_nouvel_element;
1.25 bertrand 711: }
712: else if ((*s_variable).niveau > (*((struct_variable *)
713: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
714: .donnee)).niveau)
715: {
716: // Le niveau courant n'existe pas. Il est créé.
1.1 bertrand 717:
1.40 bertrand 718: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 719: == NULL)
1.1 bertrand 720: {
721: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
722: return(d_erreur);
723: }
724:
1.25 bertrand 725: (*l_nouvelle_variable).suivant = (*s_etat_processus)
726: .l_liste_variables_par_niveau;
727: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
728: .l_liste_variables_par_niveau).precedent;
1.28 bertrand 729: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 730: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 731: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
732: .suivant = l_nouvelle_variable;
1.33 bertrand 733: (*(*s_etat_processus).l_liste_variables_par_niveau)
734: .precedent = l_nouvelle_variable;
1.25 bertrand 735:
736: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 737:
738: // Ajout de la variable en tête de la liste
739:
1.40 bertrand 740: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 741: {
742: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
743: return(d_erreur);
744: }
745:
746: (*l_nouvel_element).suivant = (*(*s_etat_processus)
747: .l_liste_variables_par_niveau).liste;
748: (*l_nouvel_element).donnee = pointeur_variable_cree;
749: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
750: l_nouvel_element;
1.25 bertrand 751: }
1.31 bertrand 752: else if ((*s_variable).niveau <= 1)
1.25 bertrand 753: {
1.33 bertrand 754: // Création d'une variable de niveau 0 ou 1. Il convient de
755: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
756: // regarde la position courante et les deux précédentes.
757:
758: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
759: niveau_acceptable = d_faux;
1.25 bertrand 760:
1.33 bertrand 761: for(i = 0; i <= 2; i++)
762: {
763: if ((*l_variable_candidate).liste == NULL)
764: {
765: continue;
766: }
767:
768: if ((*((struct_variable *) (*(*l_variable_candidate)
769: .liste).donnee)).niveau == (*s_variable).niveau)
770: {
771: niveau_acceptable = d_vrai;
772: break;
773: }
774:
775: l_variable_candidate = (*l_variable_candidate).precedent;
776: }
777:
778: if (niveau_acceptable == d_faux)
1.28 bertrand 779: {
1.40 bertrand 780: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.33 bertrand 781: == NULL)
782: {
783: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
784: return(d_erreur);
785: }
786:
787: l_variable_candidate =
788: (*(*s_etat_processus).l_liste_variables_par_niveau)
789: .precedent;
790:
791: // On ne peut créer qu'une variable de niveau supérieur ou égal à
792: // 1 lors de l'exécution normale d'un programme. Les variables
793: // de niveau 0 sont créées à l'initialisation et relèvent du
794: // cas précédent car il n'existe lors de leur création aucun
795: // niveau non nul.
796:
797: BUG((*s_variable).niveau == 0,
798: uprintf("Attempt to create a level-0 variable!\n"));
799:
800: (*l_nouvelle_variable).suivant = l_variable_candidate;
801: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
802: .precedent;
803: (*l_nouvelle_variable).noeud_pere = NULL;
804: (*l_nouvelle_variable).liste = NULL;
805: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
806: (*l_variable_candidate).precedent = l_nouvelle_variable;
807:
808: l_variable_candidate = l_nouvelle_variable;
1.28 bertrand 809: }
810:
1.33 bertrand 811: // Ajout de la variable en tête de la liste l_variable_candidate.
1.25 bertrand 812:
1.40 bertrand 813: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.25 bertrand 814: {
1.33 bertrand 815: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
816: return(d_erreur);
1.25 bertrand 817: }
818:
1.33 bertrand 819: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
820: (*l_nouvel_element).donnee = pointeur_variable_cree;
821: (*l_variable_candidate).liste = l_nouvel_element;
1.25 bertrand 822: }
1.33 bertrand 823: else
824: {
825: // Ajout de la variable en tête de la liste
1.25 bertrand 826:
1.40 bertrand 827: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 828: {
829: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
830: return(d_erreur);
831: }
1.25 bertrand 832:
1.33 bertrand 833: (*l_nouvel_element).suivant = (*(*s_etat_processus)
834: .l_liste_variables_par_niveau).liste;
835: (*l_nouvel_element).donnee = pointeur_variable_cree;
836: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
837: l_nouvel_element;
1.1 bertrand 838: }
839:
1.25 bertrand 840: return(d_absence_erreur);
841: }
842:
1.31 bertrand 843:
1.25 bertrand 844: logical1
845: creation_variable(struct_processus *s_etat_processus,
846: struct_variable *s_variable,
847: unsigned char autorisation_creation_variable_statique,
848: unsigned char autorisation_creation_variable_partagee)
849: {
1.1 bertrand 850: if ((*s_etat_processus).mode_execution_programme == 'Y')
851: {
852: (*s_variable).origine = 'P';
853: }
854: else
855: {
856: (*s_variable).origine = 'E';
857: }
858:
859: if ((*s_variable).niveau == 0)
860: {
861: // Un point d'entrée de définition est verrouillé.
862:
863: if ((*s_variable).origine == 'P')
864: {
865: (*s_variable).variable_statique.adresse = 0;
866: (*s_variable).variable_partagee.adresse = 0;
867: }
868: else
869: {
870: (*s_variable).variable_statique.pointeur = NULL;
871: (*s_variable).variable_partagee.pointeur = NULL;
872: }
873:
874: (*s_variable).variable_verrouillee = d_vrai;
875: }
876: else if ((*s_variable).niveau == 1)
877: {
878: // Une variable globale ne peut être statique.
879:
880: if ((*s_variable).origine == 'P')
881: {
882: (*s_variable).variable_statique.adresse = 0;
883: (*s_variable).variable_partagee.adresse = 0;
884: }
885: else
886: {
887: (*s_variable).variable_statique.pointeur = NULL;
888: (*s_variable).variable_partagee.pointeur = NULL;
889: }
890:
891: (*s_variable).variable_verrouillee = d_faux;
892: }
893: else
894: {
895: // 0 -> variable volatile
896: // adresse de création -> variable statique
897:
898: if (autorisation_creation_variable_statique == 'V')
899: {
900: if (autorisation_creation_variable_partagee == 'S')
901: {
902: // On force la création d'une variable partagée
903:
904: if ((*s_variable).origine == 'P')
905: {
906: (*s_variable).variable_statique.adresse = 0;
907: (*s_variable).variable_partagee.adresse =
908: (*s_etat_processus).position_courante;
909: }
910: else
911: {
912: (*s_variable).variable_statique.pointeur = NULL;
913: (*s_variable).variable_partagee.pointeur =
914: (*s_etat_processus).objet_courant;
915: }
916: }
917: else
918: {
919: // On force la création d'une variable volatile
920:
921: if ((*s_variable).origine == 'P')
922: {
923: (*s_variable).variable_statique.adresse = 0;
924: (*s_variable).variable_partagee.adresse = 0;
925: }
926: else
927: {
928: (*s_variable).variable_statique.pointeur = NULL;
929: (*s_variable).variable_partagee.pointeur = NULL;
930: }
931: }
932: }
933: else
934: {
935: // On force la création d'une variable statique.
936:
937: if ((*s_variable).origine == 'P')
938: {
939: (*s_variable).variable_statique.adresse =
940: (*s_etat_processus).position_courante;
941: (*s_variable).variable_partagee.adresse = 0;
942: }
943: else
944: {
945: (*s_variable).variable_statique.pointeur =
946: (*s_etat_processus).objet_courant;
947: (*s_variable).variable_partagee.pointeur = 0;
948: }
949: }
950:
951: (*s_variable).variable_verrouillee = d_faux;
952: }
953:
954: /*
1.25 bertrand 955: * Recherche de la feuille correspondante dans l'arbre des variables.
956: * Si cette feuille n'existe pas, elle est créée.
1.1 bertrand 957: */
958:
1.25 bertrand 959: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
960: {
961: return(d_erreur);
962: }
963:
964: return(d_absence_erreur);
965: }
966:
967:
968: /*
969: ================================================================================
970: Procédure de recherche d'une variable par son nom dans la base
971: ================================================================================
972: Entrée :
973: --------------------------------------------------------------------------------
974: Sortie :
975: --------------------------------------------------------------------------------
976: Effets de bord : néant
977: ================================================================================
978: */
979:
980: logical1
981: recherche_variable(struct_processus *s_etat_processus,
982: unsigned char *nom_variable)
983: {
984: int pointeur;
985:
986: struct_arbre_variables *l_variable_courante;
987: struct_liste_pile_systeme *l_element_courant;
988:
989: unsigned char *ptr;
990:
991: unsigned long niveau_appel;
1.1 bertrand 992:
1.25 bertrand 993: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 994: {
1.25 bertrand 995: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30 bertrand 996: return(d_faux);
1.1 bertrand 997: }
1.25 bertrand 998:
1.28 bertrand 999: l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25 bertrand 1000: ptr = nom_variable;
1001:
1002: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 1003: {
1.25 bertrand 1004: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1005:
1006: if (pointeur < 0)
1007: {
1008: // Caractère hors de l'alphabet des variables
1.30 bertrand 1009:
1010: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1011: return(d_faux);
1.25 bertrand 1012: }
1013:
1.28 bertrand 1014: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 1015: {
1.25 bertrand 1016: // Le chemin de la variable candidate n'existe pas.
1.30 bertrand 1017: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1018: return(d_faux);
1.1 bertrand 1019: }
1020:
1.28 bertrand 1021: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25 bertrand 1022: ptr++;
1023: }
1024:
1025: if ((*l_variable_courante).feuille != NULL)
1026: {
1027: // Il existe une pile de variables de même nom. Le sommet de la
1028: // pile est la variable de niveau le plus haut.
1029:
1030: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
1031:
1032: if (l_element_courant == NULL)
1.12 bertrand 1033: {
1.25 bertrand 1034: // Problème : la pile système est vide !
1035: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1036: return(d_faux);
1.12 bertrand 1037: }
1.25 bertrand 1038:
1039: while((*l_element_courant).retour_definition != 'Y')
1.12 bertrand 1040: {
1.25 bertrand 1041: l_element_courant = (*l_element_courant).suivant;
1.12 bertrand 1042:
1.25 bertrand 1043: if (l_element_courant == NULL)
1.12 bertrand 1044: {
1.25 bertrand 1045: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1046: return(d_faux);
1.12 bertrand 1047: }
1.25 bertrand 1048: }
1049:
1050: niveau_appel = (*l_element_courant).niveau_courant;
1.12 bertrand 1051:
1.25 bertrand 1052: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
1053: {
1054: // Une variable locale est accessible puisque créée dans la
1055: // fonction courante.
1056:
1057: (*s_etat_processus).pointeur_variable_courante =
1058: (*(*l_variable_courante).feuille).variable;
1059: (*s_etat_processus).pointeur_feuille_courante =
1060: (*l_variable_courante).feuille;
1.30 bertrand 1061: return(d_vrai);
1.25 bertrand 1062: }
1063: else
1064: {
1065: // Aucune variable locale n'est accessible depuis la fonction.
1066: // Dans ce cas, on prend la variable de niveau le plus bas
1067: // si ce niveau est inférieur ou égal à 1 (variable globale
1068: // ou fonction définie par l'utilisateur). Si le niveau de la
1.27 bertrand 1069: // plus ancienne variable est strictement supérieur à 1, il
1.25 bertrand 1070: // s'agit d'une variable locale inaccessible.
1071:
1072: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
1073: .niveau <= 1)
1074: {
1075: (*s_etat_processus).pointeur_variable_courante =
1076: (*(*(*l_variable_courante).feuille).precedent).variable;
1077: (*s_etat_processus).pointeur_feuille_courante =
1.33 bertrand 1078: (*(*l_variable_courante).feuille).precedent;
1.27 bertrand 1079:
1080: // S'il existe une variable de niveau 0 et une seconde de
1081: // niveau 1, la variable de niveau 0 (fonction) est masquée
1082: // par celle de niveau 1.
1083:
1.33 bertrand 1084: if (((*(*(*(*l_variable_courante).feuille).precedent)
1085: .variable).niveau == 0) && ((*(*(*(*
1086: (*l_variable_courante).feuille).precedent).precedent)
1.27 bertrand 1087: .variable).niveau == 1))
1088: {
1089: (*s_etat_processus).pointeur_variable_courante =
1.33 bertrand 1090: (*(*(*(*l_variable_courante).feuille).precedent)
1091: .precedent).variable;
1092: (*s_etat_processus).pointeur_feuille_courante =
1.27 bertrand 1093: (*(*(*l_variable_courante).feuille).precedent)
1.33 bertrand 1094: .precedent;
1.27 bertrand 1095: }
1096:
1.30 bertrand 1097: return(d_vrai);
1.12 bertrand 1098: }
1099: }
1.1 bertrand 1100: }
1101:
1.30 bertrand 1102: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1103: return(d_faux);
1.1 bertrand 1104: }
1105:
1106:
1.29 bertrand 1107: logical1
1108: recherche_variable_globale(struct_processus *s_etat_processus,
1109: unsigned char *nom)
1110: {
1111: logical1 presence_variable;
1112:
1113: presence_variable = recherche_variable(s_etat_processus, nom);
1114:
1115: if (presence_variable == d_vrai)
1116: {
1117: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
1118: {
1119: case 0:
1120: {
1.33 bertrand 1121: // La variable est une définition.
1.29 bertrand 1122: presence_variable = d_faux;
1123: break;
1124: }
1125:
1126: case 1:
1127: {
1128: break;
1129: }
1130:
1131: default:
1132: {
1133: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1134: .precedent).variable).niveau == 1)
1135: {
1136: (*s_etat_processus).pointeur_feuille_courante =
1137: (*(*s_etat_processus).pointeur_feuille_courante)
1138: .precedent;
1139: (*s_etat_processus).pointeur_variable_courante =
1140: (*(*s_etat_processus).pointeur_feuille_courante)
1141: .variable;
1142: }
1143: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
1144: .precedent).precedent).variable).niveau == 1)
1145: {
1146: (*s_etat_processus).pointeur_feuille_courante =
1147: (*(*(*s_etat_processus).pointeur_feuille_courante)
1148: .precedent).precedent;
1149: (*s_etat_processus).pointeur_variable_courante =
1150: (*(*s_etat_processus).pointeur_feuille_courante)
1151: .variable;
1152: }
1153: else
1154: {
1155: presence_variable = d_faux;
1156: }
1157:
1158: break;
1159: }
1160: }
1161: }
1162:
1163: if (presence_variable == d_vrai)
1164: {
1165: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
1166: {
1167: // La variable n'est pas globale, elle est partagée.
1168: presence_variable = d_faux;
1169: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
1170: }
1171: }
1172:
1173: return(presence_variable);
1174: }
1175:
1176:
1.1 bertrand 1177: /*
1178: ================================================================================
1179: Procédure de retrait d'une variable de la base
1180: ================================================================================
1181: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
1182: les globales) ou strictement globale.
1183: --------------------------------------------------------------------------------
1184: Sortie :
1185: --------------------------------------------------------------------------------
1186: Effets de bord : néant
1187: ================================================================================
1188: */
1189:
1190: logical1
1191: retrait_variable(struct_processus *s_etat_processus,
1192: unsigned char *nom_variable, unsigned char type)
1193: {
1.28 bertrand 1194: logical1 erreur;
1.34 bertrand 1195: logical1 variable_supprimee;
1.28 bertrand 1196:
1197: struct_arbre_variables *s_arbre_a_supprimer;
1198: struct_arbre_variables *s_arbre_courant;
1199:
1200: struct_liste_chainee *l_element_courant;
1201: struct_liste_chainee *l_element_precedent;
1202:
1203: struct_liste_variables *variable_a_supprimer;
1204: struct_liste_variables *variables_par_niveau;
1205:
1206: unsigned long niveau;
1.1 bertrand 1207:
1.36 bertrand 1208: (*s_etat_processus).niveau_supprime = d_faux;
1209:
1.1 bertrand 1210: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
1211: {
1.25 bertrand 1212: // Une variable correspondant au nom recherché est accessible.
1213:
1.1 bertrand 1214: if (type == 'G')
1215: {
1.25 bertrand 1216: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
1217: {
1218: // La variable obtenue est une variable locale. il faut
1219: // s'assurer qu'il existe une variable de niveau 1 de même
1220: // nom sur la feuille.
1221:
1.27 bertrand 1222: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1223: .precedent).variable).niveau <= 1)
1.1 bertrand 1224: {
1.27 bertrand 1225: (*s_etat_processus).pointeur_feuille_courante =
1226: (*(*s_etat_processus).pointeur_feuille_courante)
1227: .precedent;
1228: (*s_etat_processus).pointeur_variable_courante =
1229: (*(*s_etat_processus).pointeur_feuille_courante)
1230: .variable;
1231:
1232: // Si la variable retournée est de niveau 0, on regarde
1233: // un peu plus loin si une variable de niveau 1 existe.
1234:
1235: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1236: .variable).niveau == 0) &&
1237: ((*(*(*(*s_etat_processus)
1238: .pointeur_feuille_courante).precedent).variable)
1239: .niveau == 1))
1.1 bertrand 1240: {
1.27 bertrand 1241: (*s_etat_processus).pointeur_feuille_courante =
1242: (*(*s_etat_processus).pointeur_feuille_courante)
1243: .precedent;
1244: (*s_etat_processus).pointeur_variable_courante =
1245: (*(*s_etat_processus).pointeur_feuille_courante)
1246: .variable;
1.1 bertrand 1247: }
1248: }
1.27 bertrand 1249: else
1250: {
1251: // Aucune variable globale (niveau 1) n'existe.
1.1 bertrand 1252:
1.27 bertrand 1253: erreur = d_erreur;
1254: (*s_etat_processus).erreur_execution =
1255: d_ex_variable_non_definie;
1256: return(erreur);
1257: }
1.1 bertrand 1258: }
1259:
1.27 bertrand 1260: if ((*(*s_etat_processus).pointeur_variable_courante)
1.1 bertrand 1261: .variable_verrouillee == d_vrai)
1262: {
1263: erreur = d_erreur;
1264: (*s_etat_processus).erreur_execution =
1265: d_ex_variable_verrouillee;
1.28 bertrand 1266: return(erreur);
1.1 bertrand 1267: }
1268: }
1269:
1.27 bertrand 1270: // Suppression de la variable de la liste.
1271: // Deux cas peuvent survenir :
1272: // 1/ les pointeurs sur la variable et la variable suivante
1273: // sont identiques et on supprime la variable ainsi que la feuille
1274: // associée ;
1275: // 2/ ces deux pointeurs sont différents et se contente de retirer
1276: // la structure décrivant la variable.
1.1 bertrand 1277:
1.28 bertrand 1278: if ((*s_etat_processus).pointeur_feuille_courante ==
1279: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1280: {
1281: // Cas 1 :
1282: // On retire la variable du noeud en décrémentant le nombre
1283: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1284: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1285: // un nombre non nul de feuilles utilisées (ou la racine des
1286: // variables).
1287:
1288: variable_a_supprimer = (*s_etat_processus)
1289: .pointeur_feuille_courante;
1.34 bertrand 1290: s_arbre_courant = (*variable_a_supprimer).noeud;
1.28 bertrand 1291: BUG((*s_arbre_courant).noeuds_utilises == 0,
1292: uprintf("Freed node !\n"));
1293: (*s_arbre_courant).noeuds_utilises--;
1.1 bertrand 1294:
1.34 bertrand 1295: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1296: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1297: .feuille = NULL;
1298:
1.58 bertrand 1299: while(((*s_arbre_courant).noeuds_utilises == 0) &&
1300: ((*s_arbre_courant).feuille_statique == NULL))
1.28 bertrand 1301: {
1302: s_arbre_a_supprimer = s_arbre_courant;
1303: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1 bertrand 1304:
1.28 bertrand 1305: if (s_arbre_courant == NULL)
1306: {
1.40 bertrand 1307: liberation_tableau_noeuds(s_etat_processus,
1308: (*s_arbre_a_supprimer).noeuds);
1309: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.34 bertrand 1310:
1311: (*s_etat_processus).s_arbre_variables = NULL;
1.28 bertrand 1312: break;
1313: }
1314:
1.31 bertrand 1315: // s_arbre_a_supprimer contient la structure de feuille qui
1316: // vient d'être libérée. Il s'agit maintenant
1317: // d'annuler le pointeur dans le tableau noeuds de la structure
1318: // pointée par noeud_pere, soit s_arbre_courant.
1319:
1320: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1321: uprintf("Invalid pointer !\n"));
1322: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1323: .indice_tableau_pere] = NULL;
1324:
1.40 bertrand 1325: liberation_tableau_noeuds(s_etat_processus,
1326: (*s_arbre_a_supprimer).noeuds);
1327: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.31 bertrand 1328:
1.28 bertrand 1329: BUG((*s_arbre_courant).noeuds_utilises == 0,
1330: uprintf("Freed node !\n"));
1331: (*s_arbre_courant).noeuds_utilises--;
1332: }
1333: }
1334: else
1.1 bertrand 1335: {
1.28 bertrand 1336: // Cas 2 :
1337: // On retire la variable de la liste.
1338:
1339: variable_a_supprimer = (*s_etat_processus)
1340: .pointeur_feuille_courante;
1341:
1342: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1343: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1344: .suivant;
1345: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1346: .precedent = (*(*s_etat_processus)
1347: .pointeur_feuille_courante).precedent;
1.32 bertrand 1348:
1.33 bertrand 1349: // Mise à jour du pointeur dans l'arbre des variables. Cette
1350: // mise à jour n'est nécessaire que dans le cas où la variable
1351: // supprimée est en tête de la liste.
1352:
1353: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
1354: .noeuds[(*(*variable_a_supprimer).noeud)
1355: .indice_tableau_pere])).feuille)
1356: {
1357: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1358: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1359: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
1360: .noeuds[(*(*variable_a_supprimer).noeud)
1361: .indice_tableau_pere])).feuille).suivant;
1362: }
1363:
1364: (*s_etat_processus).pointeur_feuille_courante =
1365: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
1366: (*s_etat_processus).pointeur_variable_courante =
1367: (*(*s_etat_processus).pointeur_feuille_courante).variable;
1.1 bertrand 1368: }
1369:
1.28 bertrand 1370: // Dans tous les cas, on retire la variable de la liste des variables
1371: // par niveau.
1372:
1373: niveau = (*(*variable_a_supprimer).variable).niveau;
1374: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1.34 bertrand 1375: variable_supprimee = d_faux;
1.28 bertrand 1376:
1.31 bertrand 1377: if (variables_par_niveau != NULL)
1.28 bertrand 1378: {
1.31 bertrand 1379: do
1380: {
1381: l_element_courant = (*variables_par_niveau).liste;
1.28 bertrand 1382:
1.31 bertrand 1383: if (l_element_courant != NULL)
1.28 bertrand 1384: {
1.31 bertrand 1385: if ((*((struct_variable *) (*l_element_courant).donnee))
1386: .niveau == niveau)
1387: {
1388: // On parcourt le bon niveau.
1.28 bertrand 1389:
1.31 bertrand 1390: l_element_precedent = NULL;
1.28 bertrand 1391:
1.31 bertrand 1392: while(l_element_courant != NULL)
1.28 bertrand 1393: {
1.31 bertrand 1394: // Tant que l_element_courant est non nul, il reste
1395: // des variables à explorer dans le niveau courant.
1.28 bertrand 1396:
1.31 bertrand 1397: if ((*l_element_courant).donnee ==
1398: (void *) (*variable_a_supprimer).variable)
1.28 bertrand 1399: {
1.31 bertrand 1400: // On a trouvé la variable à supprimer.
1401:
1402: if (l_element_precedent == NULL)
1403: {
1404: (*variables_par_niveau).liste =
1405: (*l_element_courant).suivant;
1406: }
1407: else
1408: {
1409: (*l_element_precedent).suivant =
1410: (*l_element_courant).suivant;
1411: }
1412:
1.40 bertrand 1413: liberation_maillon(s_etat_processus,
1414: l_element_courant);
1.34 bertrand 1415:
1416: if ((*variables_par_niveau).liste == NULL)
1417: {
1.36 bertrand 1418: (*s_etat_processus).niveau_supprime =
1419: d_vrai;
1420:
1.34 bertrand 1421: if ((*s_etat_processus)
1422: .l_liste_variables_par_niveau
1423: == variables_par_niveau)
1424: {
1425: // On retire l'élément de la liste
1426: // pointé par
1427: // l_liste_variable_par_niveau
1428:
1429: (*s_etat_processus)
1430: .l_liste_variables_par_niveau =
1431: (*variables_par_niveau).suivant;
1432: }
1433:
1434: (*(*variables_par_niveau).precedent)
1435: .suivant =
1436: (*variables_par_niveau).suivant;
1437: (*(*variables_par_niveau).suivant)
1438: .precedent =
1439: (*variables_par_niveau)
1440: .precedent;
1.40 bertrand 1441: liberation_feuille(s_etat_processus,
1442: variables_par_niveau);
1.34 bertrand 1443: }
1444:
1445: variable_supprimee = d_vrai;
1.31 bertrand 1446: break;
1.28 bertrand 1447: }
1.31 bertrand 1448:
1449: l_element_precedent = l_element_courant;
1450: l_element_courant = (*l_element_courant).suivant;
1.28 bertrand 1451: }
1452: }
1453: }
1454:
1.34 bertrand 1455: if (variable_supprimee == d_vrai)
1456: {
1457: break;
1458: }
1459:
1.31 bertrand 1460: variables_par_niveau = (*variables_par_niveau).suivant;
1461:
1462: } while(variables_par_niveau != (*s_etat_processus)
1463: .l_liste_variables_par_niveau);
1.28 bertrand 1464: }
1465:
1466: // Puis on libère le contenu de la variable.
1467:
1468: free((*(*variable_a_supprimer).variable).nom);
1469: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.40 bertrand 1470: liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
1471: liberation_feuille(s_etat_processus, variable_a_supprimer);
1.28 bertrand 1472:
1.1 bertrand 1473: erreur = d_absence_erreur;
1474: }
1475: else
1476: {
1.25 bertrand 1477: // Aucune variable n'est accessible depuis le point courant du
1478: // programme.
1479:
1.1 bertrand 1480: erreur = d_erreur;
1481: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1482: }
1483:
1.25 bertrand 1484: return(erreur);
1.1 bertrand 1485: }
1486:
1487:
1488: /*
1489: ================================================================================
1490: Procédure de retrait des variables de niveau strictement supérieur au
1491: niveau courant
1492: ================================================================================
1493: Entrée :
1494: --------------------------------------------------------------------------------
1495: Sortie :
1496: --------------------------------------------------------------------------------
1497: Effets de bord : néant
1498: ================================================================================
1499: */
1500:
1501: logical1
1.59 bertrand 1502: retrait_variables_par_niveau(struct_processus *s_etat_processus)
1.1 bertrand 1503: {
1.31 bertrand 1504: struct_liste_variables *l_element_a_supprimer;
1505:
1.28 bertrand 1506: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1507: // La tête de la pile contient toujours les variables de plus haut niveau
1508: // créées.
1.1 bertrand 1509:
1.28 bertrand 1510: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1 bertrand 1511: {
1.28 bertrand 1512: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1 bertrand 1513: {
1.28 bertrand 1514: // Si le niveau ne contient aucune variable, on le détruit.
1515: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1516: // faire.
1.1 bertrand 1517: }
1518: else
1519: {
1.28 bertrand 1520: // Le niveau contient des variables.
1521:
1522: if ((*((struct_variable *) (*(*(*s_etat_processus)
1523: .l_liste_variables_par_niveau).liste).donnee)).niveau
1524: <= (*s_etat_processus).niveau_courant)
1.1 bertrand 1525: {
1.28 bertrand 1526: // On a retiré de l'arbre des variables toutes les
1527: // variables de niveau strictement supérieur au niveau
1528: // courant.
1.1 bertrand 1529:
1.28 bertrand 1530: break;
1.1 bertrand 1531: }
1.28 bertrand 1532:
1533: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1534: != NULL)
1.1 bertrand 1535: {
1.34 bertrand 1536: // Nécessaire car le pointeur sur la tête de la pile
1537: // peut être modifié par retrait_variable().
1.28 bertrand 1538: // Sauvegarde des variables statiques.
1539:
1540: if ((*((struct_variable *) (*(*(*s_etat_processus)
1541: .l_liste_variables_par_niveau).liste).donnee)).origine
1542: == 'P')
1.1 bertrand 1543: {
1.28 bertrand 1544: if ((*((struct_variable *) (*(*(*s_etat_processus)
1545: .l_liste_variables_par_niveau).liste).donnee))
1546: .variable_statique.adresse != 0)
1.1 bertrand 1547: {
1.28 bertrand 1548: if (recherche_variable_statique(s_etat_processus,
1549: (*((struct_variable *) (*(*(*s_etat_processus)
1550: .l_liste_variables_par_niveau).liste).donnee))
1551: .nom, (*((struct_variable *)
1552: (*(*(*s_etat_processus)
1553: .l_liste_variables_par_niveau).liste).donnee))
1554: .variable_statique, ((*s_etat_processus)
1555: .mode_execution_programme
1.59 bertrand 1556: == 'Y') ? 'P' : 'E') != NULL)
1.28 bertrand 1557: {
1.59 bertrand 1558: (*(*s_etat_processus)
1559: .pointeur_variable_statique_courante)
1560: .objet = (*((struct_variable *)
1.28 bertrand 1561: (*(*(*s_etat_processus)
1562: .l_liste_variables_par_niveau).liste)
1563: .donnee)).objet;
1564: }
1565: else
1566: {
1567: (*s_etat_processus).erreur_systeme =
1568: d_es_variable_introuvable;
1569: }
1570:
1571: (*((struct_variable *) (*(*(*s_etat_processus)
1572: .l_liste_variables_par_niveau).liste).donnee))
1573: .objet = NULL;
1.1 bertrand 1574: }
1.28 bertrand 1575: }
1576: else
1577: {
1578: if ((*((struct_variable *) (*(*(*s_etat_processus)
1579: .l_liste_variables_par_niveau).liste).donnee))
1580: .variable_statique.pointeur != NULL)
1.1 bertrand 1581: {
1.28 bertrand 1582: /*
1583: * Gestion des variables statiques
1584: */
1585:
1586: if (recherche_variable_statique(s_etat_processus,
1587: (*((struct_variable *) (*(*(*s_etat_processus)
1588: .l_liste_variables_par_niveau).liste).donnee))
1589: .nom, (*((struct_variable *)
1590: (*(*(*s_etat_processus)
1591: .l_liste_variables_par_niveau).liste).donnee))
1592: .variable_statique, ((*s_etat_processus)
1593: .mode_execution_programme
1.59 bertrand 1594: == 'Y') ? 'P' : 'E') != NULL)
1.28 bertrand 1595: {
1.59 bertrand 1596: (*(*s_etat_processus)
1597: .pointeur_variable_statique_courante)
1.28 bertrand 1598: .objet = (*((struct_variable *)
1599: (*(*(*s_etat_processus)
1600: .l_liste_variables_par_niveau).liste)
1601: .donnee)).objet;
1602: }
1603: else
1604: {
1605: (*s_etat_processus).erreur_systeme =
1606: d_es_variable_introuvable;
1607: return(d_erreur);
1608: }
1609:
1610: (*((struct_variable *) (*(*(*s_etat_processus)
1611: .l_liste_variables_par_niveau).liste).donnee))
1612: .objet = NULL;
1.1 bertrand 1613: }
1.28 bertrand 1614: }
1.1 bertrand 1615:
1.28 bertrand 1616: if (retrait_variable(s_etat_processus,
1617: (*((struct_variable *) (*(*(*s_etat_processus)
1618: .l_liste_variables_par_niveau).liste).donnee)).nom,
1619: 'L') == d_erreur)
1620: {
1621: return(d_erreur);
1.1 bertrand 1622: }
1.34 bertrand 1623:
1624: if ((*((struct_variable *) (*(*(*s_etat_processus)
1625: .l_liste_variables_par_niveau).liste).donnee)).niveau
1626: <= (*s_etat_processus).niveau_courant)
1627: {
1628: // On a retiré de l'arbre des variables toutes les
1629: // variables de niveau strictement supérieur au niveau
1630: // courant.
1631:
1632: return(d_absence_erreur);
1633: }
1.1 bertrand 1634: }
1635: }
1636:
1.31 bertrand 1637: // On retire l'élément de la liste doublement chaînée et circulaire.
1638:
1639: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1640: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1641: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1642: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1643:
1644: l_element_a_supprimer = (*s_etat_processus)
1645: .l_liste_variables_par_niveau;
1646: (*s_etat_processus).l_liste_variables_par_niveau =
1647: (*l_element_a_supprimer).suivant;
1.40 bertrand 1648: liberation_feuille(s_etat_processus, l_element_a_supprimer);
1.1 bertrand 1649: }
1650:
1651: return(d_absence_erreur);
1652: }
1653:
1.23 bertrand 1654:
1655: /*
1656: ================================================================================
1.24 bertrand 1657: Procédure de retrait des toutes les variables locales et globales
1658: ================================================================================
1659: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1660: de niveau 0)
1661: --------------------------------------------------------------------------------
1662: Sortie :
1663: --------------------------------------------------------------------------------
1664: Effets de bord : néant
1665: ================================================================================
1666: */
1667:
1668: void
1669: liberation_arbre_variables(struct_processus *s_etat_processus,
1670: struct_arbre_variables *arbre, logical1 retrait_definitions)
1671: {
1.58 bertrand 1672: int i;
1673:
1674: struct_liste_chainee *l_element_courant_liste;
1675: struct_liste_chainee *l_element_suivant_liste;
1.24 bertrand 1676:
1.58 bertrand 1677: struct_liste_variables *l_element_courant;
1678: struct_liste_variables *l_element_suivant;
1.28 bertrand 1679:
1.58 bertrand 1680: struct_liste_variables_statiques *l_element_statique_courant;
1681: struct_liste_variables_statiques *l_element_statique_suivant;
1.28 bertrand 1682:
1683: // Libération de l'arbre des variables. Le contenu des variables n'est
1684: // pas détruit par cette opération, il sera détruit lors de la libération
1685: // de la liste des variables par niveau.
1.24 bertrand 1686:
1.34 bertrand 1687: if (arbre == NULL)
1688: {
1689: return;
1690: }
1691:
1.31 bertrand 1692: l_element_courant = (*arbre).feuille;
1693:
1694: if (l_element_courant != NULL)
1695: {
1696: do
1697: {
1698: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1699: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1700: l_element_courant = l_element_suivant;
1701: } while(l_element_courant != (*arbre).feuille);
1.38 bertrand 1702:
1703: (*arbre).feuille = NULL;
1.31 bertrand 1704: }
1705:
1.58 bertrand 1706: l_element_statique_courant = (*arbre).feuille_statique;
1707:
1708: while(l_element_statique_courant != NULL)
1709: {
1710: l_element_statique_suivant = (*l_element_statique_courant).suivant;
1711:
1712: free((*(*l_element_statique_courant).variable).nom);
1713: liberation(s_etat_processus, (*(*l_element_statique_courant)
1714: .variable).objet);
1.61 ! bertrand 1715: free((*l_element_statique_courant).variable);
! 1716: free(l_element_statique_courant);
1.58 bertrand 1717:
1718: l_element_statique_courant = l_element_statique_suivant;
1719: }
1720:
1.24 bertrand 1721: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1722: {
1.28 bertrand 1723: if ((*arbre).noeuds[i] != NULL)
1.24 bertrand 1724: {
1.28 bertrand 1725: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1726: retrait_definitions);
1.38 bertrand 1727: (*arbre).noeuds[i] = NULL;
1.28 bertrand 1728: }
1729: }
1730:
1731: // Suppression de la liste des variables par niveau.
1732:
1733: if (arbre == (*s_etat_processus).s_arbre_variables)
1734: {
1735: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1736:
1.31 bertrand 1737: if (l_element_courant != NULL)
1.28 bertrand 1738: {
1.31 bertrand 1739: do
1740: {
1741: l_element_courant_liste = (*l_element_courant).liste;
1.24 bertrand 1742:
1.31 bertrand 1743: while(l_element_courant_liste != NULL)
1.24 bertrand 1744: {
1.31 bertrand 1745: if ((retrait_definitions == d_vrai) ||
1746: ((*((struct_variable *) (*l_element_courant_liste)
1747: .donnee)).niveau >= 1))
1748: {
1749: liberation(s_etat_processus, (*((struct_variable *)
1750: (*l_element_courant_liste).donnee)).objet);
1751: free((*((struct_variable *) (*l_element_courant_liste)
1752: .donnee)).nom);
1753: }
1754:
1755: l_element_suivant_liste =
1756: (*l_element_courant_liste).suivant;
1.40 bertrand 1757: liberation_variable(s_etat_processus, (struct_variable *)
1758: (*l_element_courant_liste).donnee);
1759: liberation_maillon(s_etat_processus,
1760: l_element_courant_liste);
1.31 bertrand 1761: l_element_courant_liste = l_element_suivant_liste;
1.24 bertrand 1762: }
1763:
1.31 bertrand 1764: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1765: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1766: l_element_courant = l_element_suivant;
1767: } while(l_element_courant != (*s_etat_processus)
1768: .l_liste_variables_par_niveau);
1.24 bertrand 1769: }
1770: }
1771:
1.40 bertrand 1772: liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
1773: liberation_noeud(s_etat_processus, arbre);
1.38 bertrand 1774: arbre = NULL;
1.24 bertrand 1775:
1776: return;
1777: }
1778:
1.28 bertrand 1779:
1.24 bertrand 1780: /*
1781: ================================================================================
1.33 bertrand 1782: Procédure renvoyant les variables dans un tableau
1783: ================================================================================
1784: Entrée :
1785: --------------------------------------------------------------------------------
1786: Sortie :
1787: --------------------------------------------------------------------------------
1788: Effets de bord : néant
1789: ================================================================================
1790: */
1791:
1792: int
1793: nombre_variables(struct_processus *s_etat_processus,
1794: struct_arbre_variables *l_element_courant)
1795: {
1.60 bertrand 1796: int i;
1797: int n;
1.33 bertrand 1798:
1.60 bertrand 1799: struct_liste_variables *l_variable;
1800: struct_liste_variables_statiques *l_variable_statique;
1.33 bertrand 1801:
1802: n = 0;
1803:
1804: if ((*l_element_courant).feuille != NULL)
1805: {
1806: l_variable = (*l_element_courant).feuille;
1807:
1808: do
1809: {
1810: n++;
1811: l_variable = (*l_variable).suivant;
1812: } while(l_variable != (*l_element_courant).feuille);
1813: }
1814:
1.60 bertrand 1815: if ((*l_element_courant).feuille_statique != NULL)
1816: {
1817: l_variable_statique = (*l_element_courant).feuille_statique;
1818:
1819: do
1820: {
1821: // Si le pointeur est nul, la variable est accessible et a été
1822: // copiée dans l'arbre des variables.
1823:
1824: if ((*(*l_variable_statique).variable).objet != NULL)
1825: {
1826: n++;
1827: }
1828:
1829: l_variable_statique = (*l_variable_statique).suivant;
1830: } while(l_variable_statique != NULL);
1831: }
1832:
1.33 bertrand 1833: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1834: {
1835: if ((*l_element_courant).noeuds[i] != NULL)
1836: {
1837: n += nombre_variables(s_etat_processus,
1838: (*l_element_courant).noeuds[i]);
1839: }
1840: }
1841:
1842: return(n);
1843: }
1844:
1.53 bertrand 1845:
1.33 bertrand 1846: int
1847: liste_variables(struct_processus *s_etat_processus,
1848: struct_tableau_variables *tableau, int position,
1849: struct_arbre_variables *l_element_courant)
1850: {
1.60 bertrand 1851: int i;
1.33 bertrand 1852:
1.60 bertrand 1853: struct_liste_variables *l_variable;
1854: struct_liste_variables_statiques *l_variable_statique;
1.33 bertrand 1855:
1856: if ((*l_element_courant).feuille != NULL)
1857: {
1858: l_variable = (*l_element_courant).feuille;
1859:
1860: do
1861: {
1862: tableau[position].origine = (*(*l_variable).variable).origine;
1863: tableau[position].nom = (*(*l_variable).variable).nom;
1864: tableau[position].niveau = (*(*l_variable).variable).niveau;
1865: tableau[position].objet = (*(*l_variable).variable).objet;
1866: tableau[position].variable_verrouillee =
1867: (*(*l_variable).variable).variable_verrouillee;
1868: tableau[position].variable_statique =
1869: (*(*l_variable).variable).variable_statique;
1870: tableau[position].variable_partagee =
1871: (*(*l_variable).variable).variable_partagee;
1.60 bertrand 1872: tableau[position].variable_masquee = d_faux;
1.33 bertrand 1873:
1874: position++;
1875: l_variable = (*l_variable).suivant;
1876: } while(l_variable != (*l_element_courant).feuille);
1877: }
1878:
1.60 bertrand 1879: if ((*l_element_courant).feuille_statique != NULL)
1880: {
1881: l_variable_statique = (*l_element_courant).feuille_statique;
1882:
1883: do
1884: {
1885: if ((*(*l_variable_statique).variable).objet != NULL)
1886: {
1887: tableau[position].origine = 'E';
1888: tableau[position].nom = (*(*l_variable_statique).variable).nom;
1889: tableau[position].niveau =
1890: (*(*l_variable_statique).variable).niveau;
1891: tableau[position].objet =
1892: (*(*l_variable_statique).variable).objet;
1893: tableau[position].variable_verrouillee = d_faux;
1894: tableau[position].variable_statique =
1895: (*(*l_variable_statique).variable).variable_statique;
1896: tableau[position].variable_partagee.pointeur = NULL;
1897: tableau[position].variable_masquee = d_vrai;
1898:
1899: position++;
1900: }
1901:
1902: l_variable_statique = (*l_variable_statique).suivant;
1903: } while(l_variable_statique != NULL);
1904: }
1905:
1.33 bertrand 1906: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1907: {
1908: if ((*l_element_courant).noeuds[i] != NULL)
1909: {
1910: position = liste_variables(s_etat_processus,
1911: tableau, position, (*l_element_courant).noeuds[i]);
1912: }
1913: }
1914:
1915: return(position);
1916: }
1917:
1.47 bertrand 1918:
1.33 bertrand 1919: /*
1920: ================================================================================
1.23 bertrand 1921: Procédure de copie de l'arbre des variables
1922: ================================================================================
1923: Entrée :
1924: --------------------------------------------------------------------------------
1925: Sortie :
1926: --------------------------------------------------------------------------------
1927: Effets de bord : néant
1928: ================================================================================
1929: */
1930:
1.38 bertrand 1931: void
1932: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
1933: *s_nouvel_etat_processus)
1.23 bertrand 1934: {
1935: // Les définitions sont partagées entre tous les threads et ne sont pas
1936: // copiées.
1.28 bertrand 1937: //
1938: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1939: // variables locales étant masquées par le processus de création de thread
1.38 bertrand 1940: // ou de processus, elles seront inaccessibles de tous les points
1941: // du fil d'exécution fils.
1942:
1943: // Pour copier ces variables, on récupère les variables depuis la liste par
1944: // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
1945: // structure. Les variables de niveau 0 étant non modifiables, elles
1946: // ne sont pas dupliquées.
1947:
1.60 bertrand 1948: int i;
1.38 bertrand 1949:
1.60 bertrand 1950: logical1 niveau_0_traite;
1951: logical1 niveau_1_traite;
1.47 bertrand 1952:
1.60 bertrand 1953: struct_arbre_variables *l_variable_courante;
1.38 bertrand 1954:
1.60 bertrand 1955: struct_liste_chainee *l_element_courant;
1.38 bertrand 1956:
1.60 bertrand 1957: struct_liste_variables *l_niveau_courant;
1958: struct_liste_variables_statiques *l_element_statique_courant;
1959:
1960: struct_variable s_variable;
1961:
1962: unsigned char *ptr;
1.38 bertrand 1963:
1964: (*s_nouvel_etat_processus).s_arbre_variables = NULL;
1965: (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
1966:
1967: l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1968:
1969: // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1.47 bertrand 1970: // 0, s'il existe est le niveau précédent la valeur courante dans la
1.38 bertrand 1971: // boucle.
1972:
1973: if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
1974: != 0)
1975: {
1976: l_niveau_courant = (*l_niveau_courant).precedent;
1977: }
1978:
1979: // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
1980: // itérations (par construction).
1.28 bertrand 1981:
1.47 bertrand 1982: niveau_0_traite = d_faux;
1983: niveau_1_traite = d_faux;
1984:
1.38 bertrand 1985: for(i = 0; i <= 2; i++)
1986: {
1987: if ((*((struct_variable *) (*(*l_niveau_courant).liste)
1988: .donnee)).niveau == 0)
1989: {
1.47 bertrand 1990: if (niveau_0_traite == d_faux)
1991: {
1992: l_element_courant = (*l_niveau_courant).liste;
1.23 bertrand 1993:
1.47 bertrand 1994: while(l_element_courant != NULL)
1.38 bertrand 1995: {
1.47 bertrand 1996: if (ajout_variable(s_nouvel_etat_processus,
1997: (struct_variable *) (*l_element_courant).donnee)
1998: == d_erreur)
1999: {
2000: return;
2001: }
2002:
2003: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 2004: }
2005:
1.47 bertrand 2006: niveau_0_traite = d_vrai;
1.38 bertrand 2007: }
2008: }
2009: else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
2010: .donnee)).niveau == 1)
2011: {
1.47 bertrand 2012: if (niveau_1_traite == d_faux)
1.38 bertrand 2013: {
1.47 bertrand 2014: l_element_courant = (*l_niveau_courant).liste;
1.38 bertrand 2015:
1.47 bertrand 2016: while(l_element_courant != NULL)
1.38 bertrand 2017: {
1.47 bertrand 2018: s_variable = (*((struct_variable *)
2019: (*l_element_courant).donnee));
1.38 bertrand 2020:
1.47 bertrand 2021: if ((s_variable.nom = strdup((*((struct_variable *)
2022: (*l_element_courant).donnee)).nom)) == NULL)
2023: {
2024: (*s_nouvel_etat_processus).erreur_systeme =
2025: d_es_allocation_memoire;
2026: return;
2027: }
2028:
2029: if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
2030: (*((struct_variable *) (*l_element_courant).donnee))
2031: .objet, 'P')) == NULL)
2032: {
2033: (*s_nouvel_etat_processus).erreur_systeme =
2034: d_es_allocation_memoire;
2035: return;
2036: }
2037:
2038: if (ajout_variable(s_nouvel_etat_processus, &s_variable)
2039: == d_erreur)
2040: {
2041: return;
2042: }
1.38 bertrand 2043:
1.47 bertrand 2044: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 2045: }
2046:
1.47 bertrand 2047: niveau_1_traite = d_vrai;
1.38 bertrand 2048: }
2049:
2050: // Les variables de niveau 0 ayant déjà été copiées, on
2051: // peut sortir de la boucle car toutes les variables sont
2052: // maintenant disponibles dans le fil d'exécution fils.
2053:
2054: break;
2055: }
2056:
2057: l_niveau_courant = (*l_niveau_courant).precedent;
2058: }
2059:
1.60 bertrand 2060: // Copie des variables statiques
2061:
2062: l_element_statique_courant = (*s_etat_processus)
2063: .l_liste_variables_statiques;
2064:
2065: while(l_element_statique_courant != NULL)
2066: {
2067: // Création des branches de l'arbre si nécessaire.
2068:
2069: if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
2070: {
2071: if (((*s_nouvel_etat_processus).s_arbre_variables =
2072: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2073: {
2074: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2075: return;
2076: }
2077:
2078: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
2079: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
2080: = NULL;
2081: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
2082: (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
2083: = -1;
2084: (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
2085:
2086: if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
2087: allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
2088: {
2089: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2090: return;
2091: }
2092:
2093: for(i = 0; i < (*s_nouvel_etat_processus)
2094: .nombre_caracteres_variables; i++)
2095: {
2096: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
2097: = NULL;
2098: }
2099: }
2100:
2101: l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
2102: ptr = (*(*l_element_statique_courant).variable).nom;
2103:
2104: while((*ptr) != d_code_fin_chaine)
2105: {
2106: BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
2107: [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
2108: (*(*l_element_statique_courant).variable).nom, *ptr));
2109:
2110: if ((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2111: .pointeurs_caracteres_variables[*ptr]] == NULL)
2112: {
2113: // Le noeud n'existe pas encore, on le crée et on le marque
2114: // comme utilisé dans la structure parente.
2115:
2116: if (((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2117: .pointeurs_caracteres_variables[*ptr]] =
2118: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2119: {
2120: (*s_etat_processus).erreur_systeme =
2121: d_es_allocation_memoire;
2122: return;
2123: }
2124:
2125: (*l_variable_courante).noeuds_utilises++;
2126:
2127: // La feuille est par défaut vide et aucun élément du tableau
2128: // noeuds (les branches qui peuvent être issues de ce nouveau
2129: // noeud) n'est encore utilisée.
2130:
2131: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2132: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
2133: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2134: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
2135: = NULL;
2136: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2137: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises
2138: = 0;
2139:
2140: // Le champ noeud_pere de la structure créée pointe sur
2141: // la structure parente et l'indice tableau_pere correspond à la
2142: // position réelle dans le tableau noeuds[] de la structure
2143: // parente du noeud courant. Cette valeur sera utilisée lors de
2144: // la destruction du noeud pour annuler le pointeur contenu dans
2145: // le tableau noeuds[] de la structure parente.
2146:
2147: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2148: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
2149: l_variable_courante;
2150: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2151: .pointeurs_caracteres_variables[*ptr]])
2152: .indice_tableau_pere = (*s_nouvel_etat_processus)
2153: .pointeurs_caracteres_variables[*ptr];
2154:
2155: // Allocation du tableau noeuds[] et initialisation à zéro de
2156: // tous les pointeurs.
2157:
2158: if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2159: .pointeurs_caracteres_variables[*ptr]]).noeuds =
2160: allocation_tableau_noeuds(s_nouvel_etat_processus))
2161: == NULL)
2162: {
2163: (*s_etat_processus).erreur_systeme
2164: = d_es_allocation_memoire;
2165: return;
2166: }
2167:
2168: for(i = 0; i < (*s_nouvel_etat_processus)
2169: .nombre_caracteres_variables; i++)
2170: {
2171: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2172: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
2173: = NULL;
2174: }
2175: }
2176:
2177: l_variable_courante = (*l_variable_courante).noeuds
2178: [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
2179: [*ptr]];
2180:
2181: ptr++;
2182: }
2183:
2184: if (creation_variable_statique(s_nouvel_etat_processus,
2185: (*l_element_statique_courant).variable) == d_erreur)
2186: {
2187: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2188: return;
2189: }
2190:
2191: l_element_statique_courant = (*l_element_statique_courant).suivant;
2192: }
2193:
1.38 bertrand 2194: return;
1.23 bertrand 2195: }
2196:
2197:
2198: /*
2199: ================================================================================
2200: Procédure d'initialisation de la table de correspondance des variables
2201: ================================================================================
2202: Entrée :
2203: --------------------------------------------------------------------------------
2204: Sortie :
2205: --------------------------------------------------------------------------------
2206: Effets de bord : néant
2207: ================================================================================
2208: */
2209:
2210: /*
2211: * Caractères autorisés dans les instructions
2212: *
2213: * 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
2214: * 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
2215: * _
2216: * 1 2 3 4 5 6 7 8 9 0
2217: */
2218:
2219: void
2220: initialisation_variables(struct_processus *s_etat_processus)
2221: {
2222: int decalage;
2223: int i;
2224: int longueur_tableau;
2225:
2226: unsigned char caractere;
2227:
2228: // Récupération de la longueur d'un unsigned char
2229:
2230: longueur_tableau = 1;
2231: decalage = 0;
2232: caractere = 1;
2233:
2234: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
2235: {
2236: decalage++;
2237: longueur_tableau *= 2;
2238: }
2239:
2240: if (((*s_etat_processus).pointeurs_caracteres_variables =
2241: malloc(longueur_tableau * sizeof(int))) == NULL)
2242: {
2243: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2244: return;
2245: }
2246:
2247: for(i = 0; i < longueur_tableau; i++)
2248: {
2249: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
2250: }
2251:
2252: (*s_etat_processus).nombre_caracteres_variables = 0;
2253:
2254: #define DECLARATION_CARACTERE(c) \
2255: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
2256: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
2257:
2258: DECLARATION_CARACTERE('A');
2259: DECLARATION_CARACTERE('B');
2260: DECLARATION_CARACTERE('C');
2261: DECLARATION_CARACTERE('D');
2262: DECLARATION_CARACTERE('E');
2263: DECLARATION_CARACTERE('F');
2264: DECLARATION_CARACTERE('G');
2265: DECLARATION_CARACTERE('H');
2266: DECLARATION_CARACTERE('I');
2267: DECLARATION_CARACTERE('J');
2268: DECLARATION_CARACTERE('K');
2269: DECLARATION_CARACTERE('L');
2270: DECLARATION_CARACTERE('M');
2271: DECLARATION_CARACTERE('N');
2272: DECLARATION_CARACTERE('O');
2273: DECLARATION_CARACTERE('P');
2274: DECLARATION_CARACTERE('Q');
2275: DECLARATION_CARACTERE('R');
2276: DECLARATION_CARACTERE('S');
2277: DECLARATION_CARACTERE('T');
2278: DECLARATION_CARACTERE('U');
2279: DECLARATION_CARACTERE('V');
2280: DECLARATION_CARACTERE('W');
2281: DECLARATION_CARACTERE('X');
2282: DECLARATION_CARACTERE('Y');
2283: DECLARATION_CARACTERE('Z');
2284:
2285: DECLARATION_CARACTERE('a');
2286: DECLARATION_CARACTERE('b');
2287: DECLARATION_CARACTERE('c');
2288: DECLARATION_CARACTERE('d');
2289: DECLARATION_CARACTERE('e');
2290: DECLARATION_CARACTERE('f');
2291: DECLARATION_CARACTERE('g');
2292: DECLARATION_CARACTERE('h');
2293: DECLARATION_CARACTERE('i');
2294: DECLARATION_CARACTERE('j');
2295: DECLARATION_CARACTERE('k');
2296: DECLARATION_CARACTERE('l');
2297: DECLARATION_CARACTERE('m');
2298: DECLARATION_CARACTERE('n');
2299: DECLARATION_CARACTERE('o');
2300: DECLARATION_CARACTERE('p');
2301: DECLARATION_CARACTERE('q');
2302: DECLARATION_CARACTERE('r');
2303: DECLARATION_CARACTERE('s');
2304: DECLARATION_CARACTERE('t');
2305: DECLARATION_CARACTERE('u');
2306: DECLARATION_CARACTERE('v');
2307: DECLARATION_CARACTERE('w');
2308: DECLARATION_CARACTERE('x');
2309: DECLARATION_CARACTERE('y');
2310: DECLARATION_CARACTERE('z');
2311:
2312: DECLARATION_CARACTERE('_');
2313:
2314: DECLARATION_CARACTERE('1');
2315: DECLARATION_CARACTERE('2');
2316: DECLARATION_CARACTERE('3');
2317: DECLARATION_CARACTERE('4');
2318: DECLARATION_CARACTERE('5');
2319: DECLARATION_CARACTERE('6');
2320: DECLARATION_CARACTERE('7');
2321: DECLARATION_CARACTERE('8');
2322: DECLARATION_CARACTERE('9');
2323: DECLARATION_CARACTERE('0');
2324: #undef DECLARATION_CARACTERE
2325:
2326: return;
2327: }
1.25 bertrand 2328:
1.1 bertrand 2329: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>