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